**

This R markdown document (.Rmd) contains analysis, visualisation and statistical testing relating to research paper “Reticular adhesions mediate cell-matrix attachment during mitosis” by Lock et al (NCB, 2018).

This code uses the R markdown framework and enables production of statistical and graphical outputs equivalent to those presented in the paper. Some purely aesthetic differences exist to final paper figures given subsequent editing (adobe illustrator) for figure embedding. All R packages necessary to run this code will be installed automatically upon running this code.

This code calls the source data file named “Supplementary Table 1 Statistics Source Data.xlsx” and selects individual data sheets pertinent to each analysis. These sheets are named according the Figure Panel that they underpin. The user must place this source data file in a location of their choice and modify the “data_input_path” variable to reflect this location. Graphical outputs are saved according to the relevant Figure Panel names (with some additional descriptive information) to a location defined by the variable “panel_output_path”. By default this is in a folder named “Graphical_Outputs” within the defined “data_input_path”. Note that some figure panels were generated directly within Excel and these can be found within the source data file.

In addition to specific .svg graphical outputs, this R markdown code will produce an HTML notebook that is useful to collectively preview and efficiently share outputs and their underlying code. This output HTML notebook file matches the name of this source .Rmd file, i.e. “Statistical_Analysis_Code_Lock_et_al_NCB_2018.nb.html”.

**

Setup

Input Path

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
# name of the source data file which you have placed in the above location data_file <- Table 1 Statistics Source Data.xlsx

Output Path

rr # Define panel output path panel_output_path <- paste(data_input_path, _Outputs/, sep = /)

Figure 1

Import Data for Figure 1

rr # Import individual data files Mass.Spec.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 1A, col_names = TRUE) b5.int.vs.VN.conc <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 1G, col_names = TRUE)

Mass Spec of Integrin subunits in long-term culture

Figure 1A boxplot of Integrin subunits spectral counts

rr #define panel_file_name Integrin_Spectral_Counts_File_Name <- 1A Integrin Spectral Counts Boxplot
boxplot(Mean.Spectral.Counts ~ Integrin.Subunit, data = Mass.Spec.Data, notch = FALSE, varwidth = FALSE, las=1, ylab = Spectral Counts, col = , ylim = c(0, 50), outline = FALSE, boxlty = 0, whisklty = 0, staplelty = 0, medlwd = 0.5, boxfill = NA) beeswarm(Mean.Spectral.Counts ~ Integrin.Subunit, data = Mass.Spec.Data, method = ‘center’, add = T, col = , pch = 19, cex = 0.7) r svglite(paste(panel_output_path, Integrin_Spectral_Counts_File_Name, .svg, sep = \), width=8, height=6) boxplot(Mean.Spectral.Counts ~ Integrin.Subunit, data = Mass.Spec.Data, notch = FALSE, varwidth = FALSE, las=1, ylab = Spectral Counts, col = , ylim = c(0, 50), outline = FALSE, boxlty = 0, whisklty = 0, staplelty = 0, medlwd = 0.5, boxfill = NA) r beeswarm(Mean.Spectral.Counts ~ Integrin.Subunit, data = Mass.Spec.Data, method = ‘center’, add = T, col = , pch = 19, cex = 0.7) dev.off()

quartz_off_screen 
                2 

T-testing for spectral count differences differences

rr AVvsB1 <- subset(Mass.Spec.Data, Integrin.Subunit ==  | Integrin.Subunit == 1) T_test_AVvsB1 <- t.test(Mean.Spectral.Counts ~ Integrin.Subunit, data = AVvsB1, alternative = .sided, paired = FALSE)$p.value T_test_AVvsB1

[1] 0.005444416

rr B5vsB1 <- subset(Mass.Spec.Data, Integrin.Subunit == 5 | Integrin.Subunit == 1) T_test_B5vsB1 <- t.test(Mean.Spectral.Counts ~ Integrin.Subunit, data = B5vsB1, alternative = .sided, paired = FALSE)$p.value T_test_B5vsB1

[1] 0.0001080229

Integrin intensity responses to Vitronection concentration in talin-positive and talin-negative adhesions

Boxplot of Integrin intensity vs Vitronection concentration in talin-positive and talin-negative adhesions

rr #define panel_file_name b5_Intensity_File_Name <- 1G Integrin b5 Intensity
names(b5.int.vs.VN.conc) <- c(_Pos_vs_Neg, , .integrin.b5.Intensity) b5.int.vs.VN.conc\(Talin_Pos_vs_Neg <- recode(b5.int.vs.VN.conc\)Talin_Pos_vs_Neg, Atypical = _Neg) b5.int.vs.VN.conc\(Talin_Pos_vs_Neg <- recode(b5.int.vs.VN.conc\)Talin_Pos_vs_Neg, typical = _Pos) b5.int.vs.VN.conc\(Group <- paste(b5.int.vs.VN.conc\)Talin_Pos_vs_Neg, b5.int.vs.VN.conc\(Condition, sep = \_\) b5.int.vs.VN.conc\)Group <- factor(b5.int.vs.VN.conc$Group, levels = c(_Pos_1VN, _Neg_1VN, _Pos_3VN, _Neg_3VN, _Pos_10VN, _Neg_10VN)) ggplot(data = b5.int.vs.VN.conc, aes(x = Group, y = Mean.integrin.b5.Intensity)) + geom_boxplot(aes(fill = Talin_Pos_vs_Neg, ymin=..lower.., ymax=..upper..), outlier.shape=NA, notch = TRUE) + scale_fill_manual(values = c(_Pos = #4F80BC, _Neg = #C0504F)) + theme_classic() + coord_cartesian(ylim = c(500, 1300)) + theme(axis.text.x = element_text(angle = 45, hjust = 1)) svglite(paste(panel_output_path, b5_Intensity_File_Name, .svg, sep = \), width=5, height=8) r ggplot(data = b5.int.vs.VN.conc, aes(x = Group, y = Mean.integrin.b5.Intensity)) + geom_boxplot(aes(fill = Talin_Pos_vs_Neg, ymin=..lower.., ymax=..upper..), outlier.shape=NA, notch = TRUE) + scale_fill_manual(values = c(_Pos = #4F80BC, _Neg = #C0504F)) + theme_classic() + coord_cartesian(ylim = c(500, 1300)) + theme(axis.text.x = element_text(angle = 45, hjust = 1)) dev.off()

quartz_off_screen 
                2 

Wilcoxon Rank Sum testing of b5 intensity changes given increased Vitronectin

rr TalinPos = subset(b5.int.vs.VN.conc, b5.int.vs.VN.conc\(Talin_Pos_vs_Neg == \Talin_Pos\) TalinPos_VN1_vs_VN3 <- subset(b5.int.vs.VN.conc, b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Pos & b5.int.vs.VN.conc\(Condition == \1VN\ | b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Pos & b5.int.vs.VN.conc\(Condition == \3VN\ ) TalinPos_VN3_vs_VN10 <- subset(b5.int.vs.VN.conc, b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Pos & b5.int.vs.VN.conc\(Condition == \3VN\ | b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Pos & b5.int.vs.VN.conc\(Condition == \10VN\ ) Mu_Test_TalinPos_VN1_vs_VN3 = wilcox.test(Mean.integrin.b5.Intensity ~ Condition, data = TalinPos_VN1_vs_VN3)\)p.value Mu_Test_TalinPos_VN3_vs_VN10 = wilcox.test(Mean.integrin.b5.Intensity ~ Condition, data = TalinPos_VN3_vs_VN10)\(p.value TalinNeg_VN1_vs_VN3 <- subset(b5.int.vs.VN.conc, b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Neg & b5.int.vs.VN.conc\(Condition == \1VN\ | b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Neg & b5.int.vs.VN.conc\(Condition == \3VN\ ) TalinNeg_VN3_vs_VN10 <- subset(b5.int.vs.VN.conc, b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Neg & b5.int.vs.VN.conc\(Condition == \3VN\ | b5.int.vs.VN.conc\)Talin_Pos_vs_Neg == _Neg & b5.int.vs.VN.conc\(Condition == \10VN\ ) Mu_Test_TalinNeg_VN1_vs_VN3 = wilcox.test(Mean.integrin.b5.Intensity ~ Condition, data = TalinNeg_VN1_vs_VN3)\)p.value Mu_Test_TalinNeg_VN3_vs_VN10 = wilcox.test(Mean.integrin.b5.Intensity ~ Condition, data = TalinNeg_VN3_vs_VN10)$p.value

Figure 2

Import Data for Figure 2

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files FRAP.data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 2S_T, col_names = TRUE) STORM.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 2V_W, col_names = TRUE)

Analysis of integrin b5 FRAP recovery curves in Reticular and Focal adhesions

Integrin b5 FRAP analysis comparing Reticular and Focal adhesions

rr #define panel_file_name FRAP_Curve_File_Name <- 2S b5 FRAP recovery
names(FRAP.data) <- c(_b5_FRAP_recovery_relative_to_prebleach, , _ROI, _vs_Focal) FRAP.data\(Reticular_vs_Focal <- recode(FRAP.data\)Reticular_vs_Focal, atypical = ) FRAP.data\(Reticular_vs_Focal <- recode(FRAP.data\)Reticular_vs_Focal, typical = ) ggplot(data=FRAP.data, aes(x=Time, y=Standardised_b5_FRAP_recovery_relative_to_prebleach, colour = Reticular_vs_Focal), alpha = 0.1) + stat_summary(fun.data =_cl_normal, alpha = 0.5) + theme_classic() + scale_colour_manual(values = c( = #BF4C49,  = #4B7FBB)) + geom_smooth(method = , span = 0.2, size = 1, fill = #3A3A3A) svglite(paste(panel_output_path, FRAP_Curve_File_Name, .svg, sep = \), width=6, height=4) r ggplot(data=FRAP.data, aes(x=Time, y=Standardised_b5_FRAP_recovery_relative_to_prebleach, colour = Reticular_vs_Focal), alpha = 0.1) + stat_summary(fun.data =_cl_normal, alpha = 0.5) + theme_classic() + scale_colour_manual(values = c( = #BF4C49,  = #4B7FBB)) + geom_smooth(method = , span = 0.2, size = 1, fill = #3A3A3A) dev.off()

quartz_off_screen 
                2 

KS test of FRAP recovery curves

rr Reticular.FRAP.data <- subset(FRAP.data, Reticular_vs_Focal == ) Focal.FRAP.data <- subset(FRAP.data, Reticular_vs_Focal == ) Reticular.FRAP.data.LOESS <- loess(Standardised_b5_FRAP_recovery_relative_to_prebleach ~ Time, data = Reticular.FRAP.data, span = 0.2) Focal.FRAP.data.LOESS <- loess(Standardised_b5_FRAP_recovery_relative_to_prebleach ~ Time, data = Focal.FRAP.data, span = 0.2) Reticular.FRAP.data.LOESS.singular <- unique(Reticular.FRAP.data.LOESS\(fitted) Focal.FRAP.data.LOESS.singular <- unique(Focal.FRAP.data.LOESS\)fitted) KS.Reticular.vs.Focal.FRAP <- ks.test(Reticular.FRAP.data.LOESS.singular, Focal.FRAP.data.LOESS.singular, alternative = .sided) print(KS.Reticular.vs.Focal.FRAP$p.value)

[1] 0.002107921

Analysis of interphase STORM data

STORM data wrangling1

rr ## Determine CMAC.type (Reticular vs Focal depending on presence of A in \(File (column)) CMAC.type = c() for (cluster in 1:length(STORM.Data\)File) ) { CMAC.type[cluster] <- if(grepl(, STORM.Data\(File[cluster]) == TRUE) { \Reticular\ } else if(grepl(\T\, STORM.Data\)File[cluster]) == TRUE) {
} else if(grepl(, STORM.Data\(File[cluster]) == TRUE) { \Non-Retraction\ } else { \Retraction\ } } STORM.Data\)CMAC.type <- cbind(as.character(CMAC.type)) ## Unique nanocluster ID generation = merge of Folder, File and Cluster # STORM.Data\(Unique.ncID <- as.factor(paste(STORM.Data\)Folder, STORM.Data\(File, STORM.Data\)Cluster)) STORM.Data\(Unique.CMACID <- as.factor(paste(STORM.Data\)Folder, STORM.Data$File)) STORM.Data <- as.data.frame(STORM.Data)

Nearest Neighbour Analysis between localisations within unique nanoclusters

rr ## NND analysis of Incite3 data NNND <- c() for (i in 1:length(unique(STORM.Data\(Unique.CMACID)) ) { temp = STORM.Data[STORM.Data\)Unique.CMACID == unique(STORM.Data$Unique.CMACID)[i], ] NNND = append(NNND, nndist(temp[,7], temp[,8], k=1)) }

NAs introduced by coercionNAs introduced by coercion

rr STORM.Data$NNND <- cbind(NNND)

Boxplots summarising Nearest Neighbout Distance per nanocluster

rr NNND.boxplot.filename <- 2V nearest neighbour boxplot
NNND.A = subset(STORM.Data\(NNND, CMAC.type == \Reticular\) NNND.T = subset(STORM.Data\)NNND, CMAC.type == ) svglite(paste(panel_output_path, NNND.boxplot.filename, .svg, sep = \), width=6, height=4) boxplot(NNND ~ CMAC.type, subset(STORM.Data, CMAC.type ==  | CMAC.type == ), notch = TRUE, outline = FALSE, main = Neighbour Distance of Nanocluster by CMAC Type, xlab = type, ylab = Neighbour Distance (nm), plot =
) dev.off()

null device 
          1 

rr boxplot(NNND ~ CMAC.type, subset(STORM.Data, CMAC.type ==  | CMAC.type == ), notch = TRUE, outline = FALSE, main = Neighbour Distance of Nanocluster by CMAC Type, xlab = type, ylab = Neighbour Distance (nm), plot =
)

Boxplots summarising Molecular Localization per nanocluster

rr Molecule.number.boxplot.filename <- 2W molecular number boxplot
Molecules.A = as.numeric(subset(STORM.Data\(Molecules, CMAC.type == \Reticular\)) Molecules.T = as.numeric(subset(STORM.Data\)Molecules, CMAC.type == )) svglite(paste(panel_output_path, Molecule.number.boxplot.filename, .svg, sep = \), width=6, height=4) boxplot(as.numeric(Molecules) ~ CMAC.type, subset(STORM.Data, CMAC.type ==  | CMAC.type == ), notch = TRUE, outline = FALSE, main = of Integrin avb5 Molecules by CMAC Type, xlab = type, ylab = of Integrin avb5 Molecules, plot =
) dev.off()

null device 
          1 

rr boxplot(as.numeric(Molecules) ~ CMAC.type, subset(STORM.Data, CMAC.type ==  | CMAC.type == ), notch = TRUE, outline = FALSE, main = of Integrin avb5 Molecules by CMAC Type, xlab = type, ylab = of Integrin avb5 Molecules, plot =
)

Figure 3

Import Data for Figure 3

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files CytoD2h_vs_control <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 3C, col_names = TRUE) CytoD2h_vs_control <- CytoD2h_vs_control[,1:3] Adhesion.Assay.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 3E, col_names = TRUE) Adhesion.Assay.Data <- Adhesion.Assay.Data[,1:4] Talin.KD.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 3H_I, col_names = TRUE)

Adhesion Assay

Fig 3E Plot Adhesion Levels per Condition

rr oldpar <- par() par(mar = c(10, 2.5, 1, 1)) #define panel_file_name Adhesion_Assay_panel_file_name <- 3E Adhesion Assay Boxplots
Adhesion.Assay.Data\(Condition <- factor(Adhesion.Assay.Data\)Condition, unique(Adhesion.Assay.Data\(Condition)) max_adhesion <- max(Adhesion.Assay.Data\)NumberObjects) Adhesion.Assay.Data\(Normalised_Adhesion <- Adhesion.Assay.Data\)NumberObjects/max_adhesion svglite(paste(panel_output_path, Adhesion_Assay_panel_file_name, .svg, sep = \), width=7.7, height=6.5) boxplot(Normalised_Adhesion ~ Condition, data = Adhesion.Assay.Data, notch = FALSE, varwidth = FALSE, outline = F, las=2, ylab = Cell Number, col = c(1wt -Cyto = #CB2327, 1wt +Cyto +RGD = #CB2327, 1b5 -Cyto = #4775A3, 1b5 -Cyto +RAD = #4775A3, 1b5 -Cyto +RGD = #9EC0E5, 1b5 +Cyto = #4775A3, 1b5 +Cyto +RAD = #4775A3, 1b5 +Cyto +RGD = #9EC0E5), ylim = c(0,1.2)) beeswarm(Normalised_Adhesion ~ Condition, data = Adhesion.Assay.Data, method = ‘center’, add = T, col = , pch = 19, cex = 0.7) dev.off()

quartz_off_screen 
                2 

rr boxplot(Normalised_Adhesion ~ Condition, data = Adhesion.Assay.Data, notch = FALSE, varwidth = FALSE, outline = F, las=2, ylab = Cell Number, col = c(1wt -Cyto = #CB2327, 1wt +Cyto +RGD = #CB2327, 1b5 -Cyto = #4775A3, 1b5 -Cyto +RAD = #4775A3, 1b5 -Cyto +RGD = #9EC0E5, 1b5 +Cyto = #4775A3, 1b5 +Cyto +RAD = #4775A3, 1b5 +Cyto +RGD = #9EC0E5), ylim = c(0,1.2)) beeswarm(Normalised_Adhesion ~ Condition, data = Adhesion.Assay.Data, method = ‘center’, add = T, col = , pch = 19, cex = 0.7)

T-testing for Adhesion Level differences with Holm-Bonferroni p-value correction

rr p_values <- c() for (i in 1:length(unique(Adhesion.Assay.Data\(Condition))){ for (j in 1:length(unique(Adhesion.Assay.Data\)Condition))){ Condition_1 = subset(Adhesion.Assay.Data, Adhesion.Assay.Data\(Condition == unique(Adhesion.Assay.Data\)Condition)[i]) Condition_1\(Condition_Number = as.factor(i) Condition_2 = subset(Adhesion.Assay.Data, Adhesion.Assay.Data\)Condition == unique(Adhesion.Assay.Data\(Condition)[j]) Condition_2\)Condition_Number = as.factor(j+100) Condition_Pair = rbind(Condition_1, Condition_2) Condition_Pair_ttest = t.test(Normalised_Adhesion ~ Condition_Number, data = Condition_Pair, paired = FALSE)\(p.value p_values = rbind(p_values, Condition_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Adhesion.Assay.Data\)Condition)),ncol = length(unique(Adhesion.Assay.Data\(Condition))) columns <- as.vector(unique(Adhesion.Assay.Data\)Condition)) rows <- as.vector(unique(Adhesion.Assay.Data\(Condition)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix1 <- matrix(corrected_p_values,nrow = length(unique(Adhesion.Assay.Data\)Condition)),ncol = length(unique(Adhesion.Assay.Data\(Condition))) columns <- as.vector(unique(Adhesion.Assay.Data\)Condition)) rows <- as.vector(unique(Adhesion.Assay.Data$Condition)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix1, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Plot heatmap of corrected p_values

rr heatmap.2(log(corrected_p_value_matrix1), dendrogram = ‘none’, Rowv = FALSE, Colv = FALSE, labRow = rows, labCol = columns, srtCol = 45, cexRow = 1, cexCol = 1, margins = c(7, 9), symm = TRUE, revC = FALSE, breaks = c(log(1e-300), log(1e-10), log(1e-6), log(0.001), log(0.01), log(0.05), log(1)), rowsep = 1:nrow(corrected_p_value_matrix1), colsep = 1:ncol(corrected_p_value_matrix1), sepcolor = ‘darkgrey’, sepwidth = c(0.02,0.02), trace = ‘none’, col = c(, , , , , ), denscol = NULL, keysize = 1.5, key.title = NA)

Wilcoxon Rank Sum testing for Adhesion Level differences

rr U_values <- c() for (i in 1:length(unique(Adhesion.Assay.Data\(Condition))){ for (j in 1:length(unique(Adhesion.Assay.Data\)Condition))){ Condition_1 = subset(Adhesion.Assay.Data, Adhesion.Assay.Data\(Condition == unique(Adhesion.Assay.Data\)Condition)[i]) Condition_1\(Condition_Number = as.factor(i) Condition_2 = subset(Adhesion.Assay.Data, Adhesion.Assay.Data\)Condition == unique(Adhesion.Assay.Data\(Condition)[j]) Condition_2\)Condition_Number = as.factor(j+100) Condition_Pair = rbind(Condition_1, Condition_2) Condition_Pair_Utest = wilcox.test(Normalised_Adhesion ~ Condition_Number, data = Condition_Pair)$p.value U_values = rbind(p_values, Condition_Pair_Utest) } }

cannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with tiescannot compute exact p-value with ties

rr U_values <- as.vector(U_values) U_value_matrix <- matrix(U_values, nrow = length(unique(Adhesion.Assay.Data\(Condition)),ncol = length(unique(Adhesion.Assay.Data\)Condition))) columns <- as.vector(unique(Adhesion.Assay.Data\(Condition)) rows <- as.vector(unique(Adhesion.Assay.Data\)Condition)) U_value_dataframe <- as.data.frame(U_value_matrix, row.names = rows) names(U_value_dataframe) <- columns print(U_value_dataframe)

Talin KD effects

Plot and test Talin KD effects on cell area and integrin b5 intensity within adhesions

rr # beeswarm(Total.Talin.per.Cell ~ siRNA..Oligo, data = Talin.KD.Data, method = ‘center’, col = , pch = 19, cex = 1, ylim = c(0,1)) # # beeswarm(Cell.Area ~ siRNA..Oligo, data = Talin.KD.Data, method = ‘center’, col = , pch = 19, cex = 1, ylim = c(0,1)) # # beeswarm(Mean.Clustered.b5.per.Cell ~ siRNA..Oligo, data = Talin.KD.Data, method = ‘center’, col = , pch = 19, cex = 1)#, ylim = c(0,1)) plot(log2(Talin.KD.Data\(Total.Talin.per.Cell), Talin.KD.Data\)Cell.Area, ylim = c(0,1), pch = c(0, 0, 0, 0, 2, 21), col = c(, , , , , )) abline(lm(Talin.KD.Data\(Cell.Area ~ log2(Talin.KD.Data\)Total.Talin.per.Cell)), col = ) r lm.cell.area_vs_talin.per.cell <- lm(Talin.KD.Data\(Cell.Area ~ log2(Talin.KD.Data\)Total.Talin.per.Cell)) TalinKD_Cell_Area_panel_file_name <- 3H TalinKD_vs_Cell_Area
svglite(paste(panel_output_path, TalinKD_Cell_Area_panel_file_name, .svg, sep = \), width=3, height=3) plot(log2(Talin.KD.Data\(Total.Talin.per.Cell), Talin.KD.Data\)Cell.Area, ylim = c(0,1), pch = c(0, 0, 0, 0, 2, 21), col = c(, , , , , ), cex.axis = 0.5, cex.label = 0.5) r abline(lm(Talin.KD.Data\(Cell.Area ~ log2(Talin.KD.Data\)Total.Talin.per.Cell)), col = ) dev.off()

quartz_off_screen 
                2 

rr plot(Talin.KD.Data\(Total.Talin.per.Cell, log2(Talin.KD.Data\)Mean.Clustered.b5.per.Cell), xlim = c(0,1), ylim = c(0,4), pch = c(0, 0, 0, 0, 2, 21), col = c(, , , , , )) abline(lm(log2(Talin.KD.Data\(Mean.Clustered.b5.per.Cell) ~ Talin.KD.Data\)Total.Talin.per.Cell), col = ) r lm.b5.intensity_vs_talin.per.cell <- lm(log2(Talin.KD.Data\(Mean.Clustered.b5.per.Cell) ~ Talin.KD.Data\)Total.Talin.per.Cell) TalinKD_b5_Intensity_panel_file_name <- 3I TalinKD_vs_b5_Intensity
svglite(paste(panel_output_path, TalinKD_b5_Intensity_panel_file_name, .svg, sep = \), width=3, height=3) plot(Talin.KD.Data\(Total.Talin.per.Cell, log2(Talin.KD.Data\)Mean.Clustered.b5.per.Cell), xlim = c(0,1), ylim = c(0,4), pch = c(0, 0, 0, 0, 2, 21), col = c(, , , , , ), cex.axis = 0.5, cex.label = 0.5) r abline(lm(log2(Talin.KD.Data\(Mean.Clustered.b5.per.Cell) ~ Talin.KD.Data\)Total.Talin.per.Cell), col = ) dev.off()

quartz_off_screen 
                2 

Test CytoD effects on adhesion intensities

Wilcoxon rank sum test of CytoD effect on vinculin and b5 intensity in adhesions

rr names(CytoD2h_vs_control) <- c(_Intensity, 5_Intensity, ) Vinculin_Intensity_mu_test <- wilcox.test(Vinculin_Intensity ~ Condition, data = CytoD2h_vs_control)$p.value print(Vinculin_Intensity_mu_test)

[1] 1.785123e-166

rr b5_Intensity_mu_test <- wilcox.test(b5_Intensity ~ Condition, data = CytoD2h_vs_control)$p.value print(b5_Intensity_mu_test)

[1] 1.624755e-99

Figure 5

Import Data for Figure 5

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files Primary.siRNA.Screen.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 5B_C, col_names = TRUE) Neo.LY.Drug.Treatment.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 5D, col_names = TRUE)

Analyse Primary siRNA Screen responses

Boxplot changes in reticular to focal adhesion b5 intensity ratio due to siRNA

rr siRNA_boxplot_summary_filename <- 5B siRNA boxplot summary
cell.numbers.primary.screen <- count(Primary.siRNA.Screen.Data, siRNA_Target) count(Primary.siRNA.Screen.Data, siRNA_Target) r mean.cell.numbers.primary.screen <- summarise(cell.numbers.primary.screen, avg = mean(n), SD = sd(n), sum(n)) summarise(cell.numbers.primary.screen, avg = mean(n), SD = sd(n), sum(n))

rr ggplot(Primary.siRNA.Screen.Data, aes(x=siRNA_Target, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(siRNA_Treatment_Type))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(,,_3Ctrl_Pool, -TARGETplus Non-targeting Control, Non-targeting Control, , 5, , 4KA, 4K2B, , 5K1B, 5K1C, 3C2A)) + theme(axis.text.x = element_text(angle=90)) + ylim(-3, 6)#+ svglite(paste(panel_output_path, siRNA_boxplot_summary_filename, .svg, sep = \), width=7, height=5) r ggplot(Primary.siRNA.Screen.Data, aes(x=siRNA_Target, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(siRNA_Treatment_Type))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(,,_3Ctrl_Pool, -TARGETplus Non-targeting Control, Non-targeting Control, , 5, , 4KA, 4K2B, , 5K1B, 5K1C, 3C2A)) + theme(axis.text.x = element_text(angle=90)) + ylim(-3, 6)#+ dev.off()

quartz_off_screen 
                2 

Parallel coordinates plot of adhesion responses to siRNA

rr siRNA_parcoord_summary_filename <- 5C siRNA parcoord summary
Primary_screen_siRNA_subset <- subset(Primary.siRNA.Screen.Data, siRNA_Target ==  | siRNA_Target ==  | siRNA_Target == _3Ctrl_Pool | siRNA_Target == -TARGETplus Non-targeting Control | siRNA_Target == Non-targeting Control | siRNA_Target ==  | siRNA_Target == 4KA | siRNA_Target == 4K2B | siRNA_Target ==  | siRNA_Target == 5K1B | siRNA_Target == 5K1C | siRNA_Target == 3C2A) Primary_screen_siRNA_subset_grouped <- aggregate(Primary_screen_siRNA_subset[, c(11,13,18)], list(Primary_screen_siRNA_subset\(siRNA_Target), median) Primary_screen_siRNA_subset_grouped\)Group.1 <- as.factor(Primary_screen_siRNA_subset_grouped$Group.1) names(Primary_screen_siRNA_subset_grouped) <- c(_Target, _Reticular_Adhesion_Intensity, _Focal_Adhesion_Intensity, _Reticular_Focal_Adhesion_Intensity) svglite(paste(panel_output_path, siRNA_parcoord_summary_filename, .svg, sep = \), width=7, height=5) ggparcoord(Primary_screen_siRNA_subset_grouped, columns = c(2,3,4), groupColumn = 1, scale = , order = c(2,3,4)) + theme(axis.text.x = element_text(angle=60, hjust = 1, size = 5)) dev.off()

null device 
          1 

rr ggparcoord(Primary_screen_siRNA_subset_grouped, columns = c(2,3,4), groupColumn = 1, scale = , order = c(2,3,4)) + theme(axis.text.x = element_text(angle=60, hjust = 1, size = 5))

Mann-Whitney test for significant siRNA treatment effects

rr siRNA.conditions.for.U.test <- subset(Primary.siRNA.Screen.Data, siRNA_Target !=  & siRNA_Target !=  & siRNA_Target != _3Ctrl_Pool & siRNA_Target != Non-targeting Control) p_values <- c() for (i in 1:length(unique(siRNA.conditions.for.U.test\(siRNA_Target))){ for (j in 1:length(unique(siRNA.conditions.for.U.test\)siRNA_Target))){ siRNA_Target_1 = subset(siRNA.conditions.for.U.test, siRNA.conditions.for.U.test\(siRNA_Target == unique(siRNA.conditions.for.U.test\)siRNA_Target)[i]) siRNA_Target_1\(siRNA_Target_Number = as.factor(i) siRNA_Target_2 = subset(siRNA.conditions.for.U.test, siRNA.conditions.for.U.test\)siRNA_Target == unique(siRNA.conditions.for.U.test\(siRNA_Target)[j]) siRNA_Target_2\)siRNA_Target_Number = as.factor(j+100) siRNA_Target_Pair = rbind(siRNA_Target_1, siRNA_Target_2) siRNA_Target_Pair_ttest = wilcox.test(Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score ~ siRNA_Target_Number, data = siRNA_Target_Pair)\(p.value p_values = rbind(p_values, siRNA_Target_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(siRNA.conditions.for.U.test\)siRNA_Target)),ncol = length(unique(siRNA.conditions.for.U.test\(siRNA_Target))) columns <- as.vector(unique(siRNA.conditions.for.U.test\)siRNA_Target)) rows <- as.vector(unique(siRNA.conditions.for.U.test\(siRNA_Target)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix2 <- matrix(corrected_p_values,nrow = length(unique(siRNA.conditions.for.U.test\)siRNA_Target)),ncol = length(unique(siRNA.conditions.for.U.test\(siRNA_Target))) columns <- as.vector(unique(siRNA.conditions.for.U.test\)siRNA_Target)) rows <- as.vector(unique(siRNA.conditions.for.U.test$siRNA_Target)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix2, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Plot heatmap of corrected p_values mann-whitney

rr heatmap.2(log(corrected_p_value_matrix2), dendrogram = ‘none’, Rowv = FALSE, Colv = FALSE, labRow = rows, labCol = columns, srtCol = 45, cexRow = 1, cexCol = 1, margins = c(7, 9), symm = TRUE, revC = FALSE, breaks = c(log(1e-300), log(1e-50), log(1e-10), log(1e-6), log(0.001), log(0.01), log(0.05), log(1)), rowsep = 1:nrow(corrected_p_value_matrix2), colsep = 1:ncol(corrected_p_value_matrix2), sepcolor = ‘darkgrey’, sepwidth = c(0.02,0.02), trace = ‘none’, col = c(, , , , , , ), denscol = NULL, keysize = 1.5, key.title = NA)

Analyse Neomycin and LY drug treatment responses

Boxplots of b5 adhesion intensity changes due to neomycin or LY

rr PIP_drug_boxplot_summary_filename <- 5D PIP drug boxplot summary
cell.numbers.NEO_LY.screen <- count(Neo.LY.Drug.Treatment.Data, Drug) count(Neo.LY.Drug.Treatment.Data, Drug) r mean.cell.numbers.NEO_LY.screen <- summarise(cell.numbers.NEO_LY.screen, avg = mean(n), SD = sd(n), sum(n)) summarise(cell.numbers.NEO_LY.screen, avg = mean(n), SD = sd(n), sum(n))

rr svglite(paste(panel_output_path, PIP_drug_boxplot_summary_filename, .svg, sep = \), width=7, height=5) p1 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Median.Mean..z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Reticular Adhesion Intensity) + theme(legend.position=) ## plot T-CMAC intensity Z-score ggplot2 boxplot - per Drug p2 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Median.Mean._T.CMACs.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Focal Adhesion Intensity) + theme(legend.position=) ## plot intensity ratio Z-score ggplot2 boxplot - per Drug p3 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Reticular:Focal Adhesion Intensity) + theme(legend.position=) grid.arrange(p1, p2, p3, ncol = 3) dev.off()

null device 
          1 

rr p1 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Median.Mean..z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Reticular Adhesion Intensity) + theme(legend.position=) ## plot T-CMAC intensity Z-score ggplot2 boxplot - per Drug p2 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Median.Mean._T.CMACs.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Focal Adhesion Intensity) + theme(legend.position=) ## plot intensity ratio Z-score ggplot2 boxplot - per Drug p3 <- ggplot(Neo.LY.Drug.Treatment.Data, aes(x=Drug, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(, _10mM,_25mM)) + theme(axis.text.x = element_text(angle=45, vjust = 0.5)) + coord_cartesian(ylim=c(-3, 6)) + ylab(Reticular:Focal Adhesion Intensity) + theme(legend.position=) grid.arrange(p1, p2, p3, ncol = 3)

Mann-Whitney test for significant Drug treatment effects on Reticular adhesion intensity

rr p_values <- c() for (i in 1:length(unique(Neo.LY.Drug.Treatment.Data\(Drug))){ for (j in 1:length(unique(Neo.LY.Drug.Treatment.Data\)Drug))){ Drug_1 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\(Drug == unique(Neo.LY.Drug.Treatment.Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\)Drug == unique(Neo.LY.Drug.Treatment.Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(Median.Mean..z.score ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix3 <- matrix(corrected_p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix3, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Mann-Whitney test for significant Drug treatment effects on Focal adhesion intensity

rr p_values <- c() for (i in 1:length(unique(Neo.LY.Drug.Treatment.Data\(Drug))){ for (j in 1:length(unique(Neo.LY.Drug.Treatment.Data\)Drug))){ Drug_1 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\(Drug == unique(Neo.LY.Drug.Treatment.Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\)Drug == unique(Neo.LY.Drug.Treatment.Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(Median.Mean._T.CMACs.z.score ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix4 <- matrix(corrected_p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix4, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Mann-Whitney test for significant Drug treatment effects on intensity ratio Z-score

rr p_values <- c() for (i in 1:length(unique(Neo.LY.Drug.Treatment.Data\(Drug))){ for (j in 1:length(unique(Neo.LY.Drug.Treatment.Data\)Drug))){ Drug_1 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\(Drug == unique(Neo.LY.Drug.Treatment.Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Neo.LY.Drug.Treatment.Data, Neo.LY.Drug.Treatment.Data\)Drug == unique(Neo.LY.Drug.Treatment.Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(as.numeric(Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score) ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix5 <- matrix(corrected_p_values,nrow = length(unique(Neo.LY.Drug.Treatment.Data\)Drug)),ncol = length(unique(Neo.LY.Drug.Treatment.Data\(Drug))) columns <- as.vector(unique(Neo.LY.Drug.Treatment.Data\)Drug)) rows <- as.vector(unique(Neo.LY.Drug.Treatment.Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix5, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Figure 6

Import Data for Figure 6

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files Proliferation <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 6A, col_names = TRUE) Proliferation\(Day <- as.factor(Proliferation\)Day) EDU_Incorporation_Percentage <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 6B, col_names = TRUE) EDU_Incorporation_Percentage <- EDU_Incorporation_Percentage[,1:2]

Summarise Proliferation data per Condition per Day

rr Prol_Sum <- Proliferation %>% group_by(.dots = c(‘Condition’, ‘Day’)) %>% summarise( mean_proliferation = mean(Relative.Proliferation, na.rm = TRUE), SD_proliferation = sd(Relative.Proliferation, na.rm = TRUE) )

Plot Cell Proliferation Comparison of control vs b5KD

rr proliferation_linechart_filename <- 6A proliferation linechart
# The errorbars overlapped, so use position_dodge to move them horizontally pd <- position_dodge(0.1) # move them .05 to the left and right svglite(paste(panel_output_path, proliferation_linechart_filename, .svg, sep = \), width=4, height=3) ggplot(Prol_Sum, aes(x=Day, y=mean_proliferation, colour=Condition, group=Condition)) + geom_errorbar(aes(ymin=mean_proliferation-SD_proliferation, ymax=mean_proliferation+SD_proliferation), width=.1, position=pd) + scale_color_manual(values = c( = #49494A, 5KD = #EC1C24)) + geom_line(position=pd, size = 1) + geom_point(position=pd, size=3, shape=19) + # 21 is filled circle xlab() + ylab(Proliferation) + theme_light() dev.off()

null device 
          1 

rr ggplot(Prol_Sum, aes(x=Day, y=mean_proliferation, colour=Condition, group=Condition)) + geom_errorbar(aes(ymin=mean_proliferation-SD_proliferation, ymax=mean_proliferation+SD_proliferation), width=.1, position=pd) + scale_color_manual(values = c( = #49494A, 5KD = #EC1C24)) + geom_line(position=pd, size = 1) + geom_point(position=pd, size=3, shape=19) + # 21 is filled circle xlab() + ylab(Proliferation) + theme_light()

T-testing Cell Proliferation Comparison per Condition per Day

rr Proliferation\(Day <- as.factor(Proliferation\)Day) p_values <- c() for (i in 1:length(unique(Proliferation$Day))){

single_day_data = subset(Proliferation, Proliferation$Day == unique(Proliferation$Day)[i])

Control_vs_b5KD_per_day_ttest = t.test(Relative.Proliferation ~ Condition, data = single_day_data, paired = FALSE)$p.value
p_values = rbind(p_values, Control_vs_b5KD_per_day_ttest)

} p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = 1,ncol = length(p_values)) columns <- as.vector(paste(, unique(Proliferation\(Day), sep = \ \)) rows <- paste(unique(Proliferation\)Condition)[1], unique(Proliferation$Condition)[2], sep = _vs_) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns print(p_value_dataframe)

EDU Incorporation Comparison per Condition

Fig 6B Plot EDU Incorporation Boxplot per Condition

rr #define panel_file_name EDU_boxplot_panel_file_name <- 6B EDU Incorporation Boxplots
EDU_Incorporation_Percentage\(Condition <- factor(EDU_Incorporation_Percentage\)Condition, c(, 5KD)) svglite(paste(panel_output_path, EDU_boxplot_panel_file_name, .svg, sep = \), width=4, height=6) boxplot(Percentage.EDU.positive.Cells.per.image ~ Condition, data = EDU_Incorporation_Percentage, notch = T, varwidth = T, outline = F, ylab = % EDU positive cells, col = c(control = #49494A, b5KD = #EC1C24), ylim = c(0,115)) beeswarm(Percentage.EDU.positive.Cells.per.image ~ Condition, data = EDU_Incorporation_Percentage, method = ‘center’, add = T, col = 2, pch = 1, cex = 1.3) dev.off()

null device 
          1 

rr boxplot(Percentage.EDU.positive.Cells.per.image ~ Condition, data = EDU_Incorporation_Percentage, notch = T, varwidth = T, outline = F, ylab = % EDU positive cells, col = c(control = #49494A, b5KD = #EC1C24), ylim = c(0,115)) r beeswarm(Percentage.EDU.positive.Cells.per.image ~ Condition, data = EDU_Incorporation_Percentage, method = ‘center’, add = T, col = 2, pch = 1, cex = 1.3)

Fig6B Mann-Whitney µ test for EDU Incorporation differences

rr #Note: Equivalent to Wilcoxon rank sum test as data is unpaired Utest.b5KD.vs.control_EDU <- wilcox.test(Percentage.EDU.positive.Cells.per.image ~ Condition, data = EDU_Incorporation_Percentage)

cannot compute exact p-value with ties

rr Mann_Whitney_EDU_Incorporation_Score <- Utest.b5KD.vs.control_EDU$p.value print(Mann_Whitney_EDU_Incorporation_Score)

[1] 0.5337576

Figure 7

Import Data for Figure 7

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files STORM.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 7E_F, col_names = TRUE)

Analysis of mitotic STORM data

STORM data wrangling2

rr ## Determine CMAC.type (Reticular vs Focal depending on presence of A in \(File (column)) CMAC.type = c() for (cluster in 1:length(STORM.Data\)File) ) { CMAC.type[cluster] <- if(grepl(, STORM.Data\(File[cluster]) == TRUE) { \Reticular\ } else if(grepl(\T\, STORM.Data\)File[cluster]) == TRUE) {
} else if(grepl(, STORM.Data\(File[cluster]) == TRUE) { \Non-Retraction\ } else { \Retraction\ } } STORM.Data\)CMAC.type <- cbind(as.character(CMAC.type)) ## Unique nanocluster ID generation = merge of Folder, File and Cluster STORM.Data\(Unique.ncID <- as.factor(paste(STORM.Data\)Folder, STORM.Data\(File, STORM.Data\)Cluster)) STORM.Data\(Unique.CMACID <- as.factor(paste(STORM.Data\)Folder, STORM.Data$File))

Nearest Neighbour Analysis between localisations within unique nanoclusters2

rr ## NND analysis of Incite3 data NNND <- c() for (i in 1:length(unique(STORM.Data\(Unique.CMACID)) ) { temp = STORM.Data[STORM.Data\)Unique.CMACID == unique(STORM.Data\(Unique.CMACID)[i], ] NNND = append(NNND, nndist(temp\)Centroid.nm., temp$Centroid.nm..1, k=1)) }

NAs introduced by coercionNAs introduced by coercion

rr STORM.Data$NNND <- cbind(NNND)

Boxplots summarising Nearest Neighbout Distance per nanocluster2

rr NNND.A = subset(STORM.Data\(NNND, CMAC.type == \Non-Retraction\) NNND.T = subset(STORM.Data\)NNND, CMAC.type == ) TEST_nnnd_NRvsR <- wilcox.test(NNND.A, NNND.T, paired = FALSE) NNND_boxplot_filename <- 7E NNND boxplot
svglite(paste(panel_output_path, NNND_boxplot_filename, .svg, sep = \), width=4, height=3) boxplot(NNND ~ CMAC.type, subset(STORM.Data, CMAC.type == -Retraction | CMAC.type == ), notch = TRUE, outline = FALSE, main = Neighbour Distance of Nanocluster by CMAC Type, sub = TEST_nnnd_NRvsR$p.value, xlab = type, ylab = Neighbour Distance (nm), plot =
) dev.off()

null device 
          1 

rr boxplot(NNND ~ CMAC.type, subset(STORM.Data, CMAC.type == -Retraction | CMAC.type == ), notch = TRUE, outline = FALSE, main = Neighbour Distance of Nanocluster by CMAC Type, sub = TEST_nnnd_NRvsR$p.value, xlab = type, ylab = Neighbour Distance (nm), plot =
)

Boxplots summarising Molecular Localization per nanocluster2

rr STORM.Data\(Molecules <- as.numeric(STORM.Data\)Molecules)

NAs introduced by coercion

rr Molecules.A = subset(STORM.Data\(Molecules, CMAC.type == \Non-Retraction\) Molecules.T = subset(STORM.Data\)Molecules, CMAC.type == ) Mol_Count_boxplot_filename <- 7F Molecule Count boxplot
svglite(paste(panel_output_path, Mol_Count_boxplot_filename, .svg, sep = \), width=4, height=3) TEST_Molecules.A_RetvsFoc <- wilcox.test(Molecules.A, Molecules.T, paired = FALSE) boxplot(Molecules ~ CMAC.type, subset(STORM.Data, CMAC.type == -Retraction | CMAC.type == ), notch = TRUE,outline = FALSE, main = of Integrin avb5 Molecules by CMAC Type, sub = TEST_Molecules.A_RetvsFoc$p.value, xlab = type, ylab = of Integrin avb5 Molecules, plot =
) dev.off()

null device 
          1 

rr TEST_Molecules.A_RetvsFoc <- wilcox.test(Molecules.A, Molecules.T, paired = FALSE) boxplot(Molecules ~ CMAC.type, subset(STORM.Data, CMAC.type == -Retraction | CMAC.type == ), notch = TRUE,outline = FALSE, main = of Integrin avb5 Molecules by CMAC Type, sub = TEST_Molecules.A_RetvsFoc$p.value, xlab = type, ylab = of Integrin avb5 Molecules, plot =
)

Figure 8

Import Data for Figure 8

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files Residual_Angle_data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 8A_B, col_names = TRUE) Cell_Division_Defect_Quantification <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 8C, col_names = TRUE) Cell_Division_Defect_Quantification <- Cell_Division_Defect_Quantification[1:9, 1:4]

Residual Angle Comparisons per Condition

Fig 8A Plot Residual Angle Boxplot of +/- Beeswarm by condition

rr #define panel_file_name boxplot_panel_file_name <- 8A Residual Angle Boxplots
# oldpar <- par() # par(mfrow = c(1,1), mar = c(5,5,1,1)) Residual_Angle_dataCN <- Residual_Angle_data # Set Condition order Residual_Angle_dataCN\(Condition <- factor(Residual_Angle_dataCN\)Condition, c(, 5KD, )) svglite(paste(panel_output_path, boxplot_panel_file_name, .svg, sep = \), width=4, height=6) boxplot(Pre.to.Post.Mitosis.Angle ~ Condition, data = Residual_Angle_dataCN, notch = T, varwidth = T, outline = F, ylab = Angle, col = c(control = #49494A, b5KD = #EC1C24, Rescue = #BCBCBC), ylim = c(0,115)) beeswarm(Pre.to.Post.Mitosis.Angle ~ Condition, data = Residual_Angle_dataCN, method = ‘center’, add = T, col = 2, pch = 1, cex = 0.5) dev.off()

null device 
          1 

rr boxplot(Pre.to.Post.Mitosis.Angle ~ Condition, data = Residual_Angle_dataCN, notch = T, varwidth = T, outline = F, ylab = Angle, col = c(control = #49494A, b5KD = #EC1C24, Rescue = #BCBCBC), ylim = c(0,115)) r beeswarm(Pre.to.Post.Mitosis.Angle ~ Condition, data = Residual_Angle_dataCN, method = ‘center’, add = T, col = 2, pch = 1, cex = 0.5)

Fig 8B Plot Residual Angle smoothed density plot per condition

rr #define panel_file_name density_panel_file_name <- 8B Residual Angle Density Plot
svglite(paste(panel_output_path, density_panel_file_name, .svg, sep = \), width=4, height=6) sm.density.compare(Residual_Angle_dataCN\(Pre.to.Post.Mitosis.Angle, Residual_Angle_dataCN\)Condition, col = c(#49494A, #EC1C24, #BCBCBC), lty = c(1,1,1), lwd = 2, h = 5, xlim = c(0,90), xlab = Angle) colfill<-c(#49494A, #EC1C24, #BCBCBC) legend(x=40, y=0.033, levels(Residual_Angle_dataCN$Condition), fill=colfill, bty = ) dev.off()

null device 
          1 

rr sm.density.compare(Residual_Angle_dataCN\(Pre.to.Post.Mitosis.Angle, Residual_Angle_dataCN\)Condition, col = c(#49494A, #EC1C24, #BCBCBC), lty = c(1,1,1), lwd = 2, h = 5, xlim = c(0,90), xlab = Angle) r colfill<-c(#49494A, #EC1C24, #BCBCBC) legend(x=40, y=0.033, levels(Residual_Angle_dataCN$Condition), fill=colfill, bty = )

Count cell number per condition

rr Residual_Angle_dataCN %>% group_by(Condition) %>% summarise( n = n())

Mann-Whitney µ test for Residual Angle differences

rr #Note: Equivalent to Wilcoxon rank sum test as data is unpaired b5KD_Control <- subset(Residual_Angle_data, Residual_Angle_data\(Condition == \b5KD\ | Residual_Angle_data\)Condition == ) Utest.b5KD.vs.control <- wilcox.test(Pre.to.Post.Mitosis.Angle ~ Condition, data = b5KD_Control) Utest.b5KD.vs.control.pval <- Utest.b5KD.vs.control\(p.value b5KD_Rescue <- subset(Residual_Angle_data, Residual_Angle_data\)Condition == 5KD | Residual_Angle_data\(Condition == \Rescue\) Utest.b5KD.vs.Rescue <- wilcox.test(Pre.to.Post.Mitosis.Angle ~ Condition, data = b5KD_Rescue) Utest.b5KD.vs.Rescue.pval <- Utest.b5KD.vs.Rescue\)p.value Control_Rescue <- subset(Residual_Angle_data, Residual_Angle_data\(Condition == \Control\ | Residual_Angle_data\)Condition == ) Utest.control.vs.Rescue <- wilcox.test(Pre.to.Post.Mitosis.Angle ~ Condition, data = Control_Rescue) Utest.control.vs.Rescue.pval <- Utest.control.vs.Rescue\(p.value Mann_Whitney_Scores <- data.frame(Condition_Comparison = c(\b5KD_vs_Control\, \b5KD_vs_Rescue\, \Control_vs_Rescue\)) Mann_Whitney_Scores\)pvalue <- rbind(Utest.b5KD.vs.control.pval, Utest.b5KD.vs.Rescue.pval, Utest.control.vs.Rescue.pval) print(Mann_Whitney_Scores)

Residual Angle Comparisons per Condition per Experiment

Plot Residual Angle Boxplot by condition by experiment

rr Residual_Angle_dataFN <- Residual_Angle_data Residual_Angle_dataFN\(File.Name <- factor(Residual_Angle_dataFN\)File.Name, c(_3_MMStack_control Hela 01.ome.tif, _3_MMStack_control Hela 02.ome.tif, _3_MMStack_b5 KD plus GFP 01.ome.tif, _3_MMStack_b5 KD plus GFP 02.ome.tif, _3_MMStack_b5 KD plus WTb5-GFP 01.ome.tif, _3_MMStack_b5 KD plus WTb5-GFP 02.ome.tif)) boxplot(Pre.to.Post.Mitosis.Angle ~ File.Name, data = Residual_Angle_dataFN, notch = T, varwidth = T, outline = F, ylab = Angle, col = c(#49494A, #49494A, #EC1C24, #EC1C24,#BCBCBC, #BCBCBC), ylim = c(0,115), names = c(_01, _02, 5KD_01, 5KD_02, _01, _02))

rr # beeswarm(Pre.to.Post.Mitosis.Angle ~ File.Name, data = Residual_Angle_dataFN, method = ‘swarm’, add = T, col = 2, pch = 0, cex = 0.7)

Plot Plot Residual Angle smoothed density plot per condition per experiment

rr sm.density.compare(Residual_Angle_dataFN\(Pre.to.Post.Mitosis.Angle, Residual_Angle_dataFN\)File.Name, col = c(#49494A, #49494A, #EC1C24, #EC1C24,#BCBCBC,#BCBCBC), h=5, lty = c(1,5,1,5,1,5), lwd = 2, xlim = c(0,90), xlab = Angle) legend(x=23, y= 0.05, levels(Residual_Angle_dataFN$File.Name), fill=c(#49494A, #49494A, #EC1C24, #EC1C24,#BCBCBC,#BCBCBC), bty = ‘n’)

Count cell number per condition per experiment

rr Residual_Angle_dataFN %>% group_by(File.Name) %>% summarise( n = n())

Cell Division Defect Quantification

Fig 8C Cell Division Defect Rate Plotting

rr CDD_boxplot_panel_file_name <- 8C Cell Division Defect Rate Boxplot
Cell_Division_Defect_Quantification\(Condition <- factor(Cell_Division_Defect_Quantification\)Condition, c(, 5KD, )) svglite(paste(panel_output_path, CDD_boxplot_panel_file_name, .svg, sep = \), width=4, height=6) boxplot(normal.cell.division ~ Condition, data = Cell_Division_Defect_Quantification, outline = FALSE, boxlty = 0, whisklty = 0, staplelty = 0, ylab = Division Percentage, ylim = c(0,115), medlwd = 0.0) beeswarm(normal.cell.division ~ Condition, data = Cell_Division_Defect_Quantification, method = ‘center’, add = T, col = c(control = #49494A, b5KD = #EC1C24, Rescue = #BCBCBC), ylim = c(0,115), pch = 19, cex = 1.3) dev.off()

null device 
          1 

rr boxplot(normal.cell.division ~ Condition, data = Cell_Division_Defect_Quantification, outline = FALSE, boxlty = 0, whisklty = 0, staplelty = 0, ylab = Division Percentage, ylim = c(0,115), medlwd = 0.0) r beeswarm(normal.cell.division ~ Condition, data = Cell_Division_Defect_Quantification, method = ‘center’, add = T, col = c(control = #49494A, b5KD = #EC1C24, Rescue = #BCBCBC), ylim = c(0,115), pch = 19, cex = 1.3)

Cell Division Defect Summaries

rr Division_Defect_Summary <- Cell_Division_Defect_Quantification %>% group_by(Condition) %>% summarise( Normal_Division = mean(normal.cell.division), Abnormal_Division = mean(abnormal.cell.division) )

print(Division_Defect_Summary)

T-testing for Cell Division Defect Rate differences

rr b5KD_Control_CDD <- subset(Cell_Division_Defect_Quantification, Condition == 5KD | Condition == ) T_test_b5KD_Control_CDD <- t.test(normal.cell.division ~ Condition, data = b5KD_Control_CDD)\(p.value b5KD_Rescue_CDD <- subset(Cell_Division_Defect_Quantification, Condition == \b5KD\ | Condition == \Rescue\) T_test_b5KD_Rescue_CDD <- t.test(normal.cell.division ~ Condition, data = b5KD_Rescue_CDD)\)p.value Control_Rescue_CDD <- subset(Cell_Division_Defect_Quantification, Condition ==  | Condition == ) T_test_Control_Rescue_CDD <- t.test(normal.cell.division ~ Condition, data = Control_Rescue_CDD)\(p.value Ttest_Scores_CDD <- data.frame(Condition_Comparison = c(\b5KD_Control_CDD\, \b5KD_Rescue_CDD\, \Control_Rescue_CDD\)) Ttest_Scores_CDD\)pvalue <- rbind(T_test_b5KD_Control_CDD, T_test_b5KD_Rescue_CDD, T_test_Control_Rescue_CDD) print(Ttest_Scores_CDD)

Supp Fig 5

Import Data Supp Fig 5

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files Arp23_Inhibition_Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 5C, col_names = TRUE) Arp23_Inhibition_Data\(Drug <- recode(Arp23_Inhibition_Data\)Drug, Arp_Inhib_CTRL_689 = _CTRL_689)

Analyse Arp2/3 inhibitor responses relative to control

Boxplot changes in reticular adhesion b5 intensity2

rr Arp23_b5_intensity_boxplots_filename <- SF5C Arp23_b5_intensity_boxplots
cell.numbers.ARP23.screen <- count(Arp23_Inhibition_Data, Drug) count(Arp23_Inhibition_Data, Drug) r mean.cell.numbers.ARP23.screen <- summarise(cell.numbers.ARP23.screen, avg = mean(n), SD = sd(n), sum(n)) summarise(cell.numbers.ARP23.screen, avg = mean(n), SD = sd(n), sum(n))

rr svglite(paste(panel_output_path, Arp23_b5_intensity_boxplots_filename, .svg, sep = \), width=7, height=5) p1 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Median.Mean..z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Reticular Adhesion Intensity) + theme(legend.position=) ## plot T-CMAC intensity Z-score ggplot2 boxplot - per Drug p2 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Median.Mean._T.CMACs.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Focal Adhesion Intensity) + theme(legend.position=) ## plot intensity ratio Z-score ggplot2 boxplot - per Drug p3 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Reticular:Focal Adhesion Intensity) + theme(legend.position=) grid.arrange(p1, p2, p3, ncol = 3) dev.off()

null device 
          1 

rr p1 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Median.Mean..z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Reticular Adhesion Intensity) + theme(legend.position=) ## plot T-CMAC intensity Z-score ggplot2 boxplot - per Drug p2 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Median.Mean._T.CMACs.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Focal Adhesion Intensity) + theme(legend.position=) ## plot intensity ratio Z-score ggplot2 boxplot - per Drug p3 <- ggplot(Arp23_Inhibition_Data, aes(x=Drug, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(Drug))) + geom_boxplot(notch = TRUE, outlier.colour = ) + scale_x_discrete(limits=c(_CTRL_689, _Inhib_666)) + theme(axis.text.x = element_text(angle=45, hjust = 1)) + ylim(-3, 6) + ylab(Reticular:Focal Adhesion Intensity) + theme(legend.position=) grid.arrange(p1, p2, p3, ncol = 3)

Mann-Whitney test for significant Drug treatment effects on Reticular adhesion intensity2

rr p_values <- c() for (i in 1:length(unique(Arp23_Inhibition_Data\(Drug))){ for (j in 1:length(unique(Arp23_Inhibition_Data\)Drug))){ Drug_1 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\(Drug == unique(Arp23_Inhibition_Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\)Drug == unique(Arp23_Inhibition_Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(Median.Mean..z.score ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix6 <- matrix(corrected_p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix6, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Mann-Whitney test for significant Drug treatment effects on Focal adhesion intensity2

rr p_values <- c() for (i in 1:length(unique(Arp23_Inhibition_Data\(Drug))){ for (j in 1:length(unique(Arp23_Inhibition_Data\)Drug))){ Drug_1 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\(Drug == unique(Arp23_Inhibition_Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\)Drug == unique(Arp23_Inhibition_Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(Median.Mean._T.CMACs.z.score ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix7 <- matrix(corrected_p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix7, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Mann-Whitney test for significant Drug treatment effects on intensity ratio Z-score2

rr p_values <- c() for (i in 1:length(unique(Arp23_Inhibition_Data\(Drug))){ for (j in 1:length(unique(Arp23_Inhibition_Data\)Drug))){ Drug_1 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\(Drug == unique(Arp23_Inhibition_Data\)Drug)[i]) Drug_1\(Drug_Number = as.factor(i) Drug_2 = subset(Arp23_Inhibition_Data, Arp23_Inhibition_Data\)Drug == unique(Arp23_Inhibition_Data\(Drug)[j]) Drug_2\)Drug_Number = as.factor(j+100) Drug_Pair = rbind(Drug_1, Drug_2) Drug_Pair_ttest = wilcox.test(Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score ~ Drug_Number, data = Drug_Pair)\(p.value p_values = rbind(p_values, Drug_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data\(Drug)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix8 <- matrix(corrected_p_values,nrow = length(unique(Arp23_Inhibition_Data\)Drug)),ncol = length(unique(Arp23_Inhibition_Data\(Drug))) columns <- as.vector(unique(Arp23_Inhibition_Data\)Drug)) rows <- as.vector(unique(Arp23_Inhibition_Data$Drug)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix8, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Supp Fig 6

Import Data Supp Fig 6

rr # Set your path to input data data_input_path <- /Users/johnlock/Dropbox/A-CMAC Manchester collaboration/NCB submission documents/Resubmission 2/Source_Data
data_file <- Table 1 Statistics Source Data.xlsx
# Import individual data files Secondary.siRNA.Screen.Data <- read_xlsx(paste(data_input_path, data_file, sep = /), sheet = 6A, col_names = TRUE)

Analyse Secondary siRNA Screen responses

Boxplot changes in reticular to focal adhesion b5 intensity ratio

rr Secondary_siRNA_Screen_boxplots_filename <- SF6A Secondary_siRNA_Screen_boxplot_summary
Secondary.siRNA.Screen.Data\(siRNA_Target <- recode(Secondary.siRNA.Screen.Data\)siRNA_Target, PIK3C2a_1 = 3C2A_1) Secondary.siRNA.Screen.Data\(siRNA_Target <- recode(Secondary.siRNA.Screen.Data\)siRNA_Target, PIK3C2a_2 = 3C2A_2) Secondary.siRNA.Screen.Data\(siRNA_Target <- recode(Secondary.siRNA.Screen.Data\)siRNA_Target, PIK3C2a_3 = 3C2A_3) Secondary.siRNA.Screen.Data\(siRNA_Target <- recode(Secondary.siRNA.Screen.Data\)siRNA_Target, PIK3C2a_4 = 3C2A_4) cell.numbers.secondary.screen <- count(Secondary.siRNA.Screen.Data, siRNA_Target) count(Secondary.siRNA.Screen.Data, siRNA_Target) r mean.cell.numbers.secondary.screen <- summarise(cell.numbers.secondary.screen, avg = mean(n), SD = sd(n), sum(n)) summarise(cell.numbers.secondary.screen, avg = mean(n), SD = sd(n), sum(n))

rr svglite(paste(panel_output_path, Secondary_siRNA_Screen_boxplots_filename, .svg, sep = \), width=7, height=5) ggplot(Secondary.siRNA.Screen.Data, aes(x=siRNA_Target, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(siRNA_Treatment_Type))) + geom_boxplot(notch = TRUE, outlier.colour = ) + theme(axis.text.x = element_text(angle=90)) + ylim(-3, 6) + scale_x_discrete(limits=c(,,_3Ctrl_Pool, -TARGETplus Non-targeting Control, Non-targeting Control, , , 5, _1, _2, _3, _4, 4K2A_1, 4K2A_2, 4K2A_3, 4K2A_4, 4KA_1, 4KA_2, 4KA_3, 4KA_4, 5K1B_1, 5K1B_2, 5K1B_3, 5K1B_4, 5K1C_1, 5K1C_2, 5K1C_3, 5K1C_4, _1, _2, _3, _4, 3C2A_1, 3C2A_2, 3C2A_3, 3C2A_4)) dev.off()

null device 
          1 

rr ggplot(Secondary.siRNA.Screen.Data, aes(x=siRNA_Target, y=Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score, color = factor(siRNA_Treatment_Type))) + geom_boxplot(notch = TRUE, outlier.colour = ) + theme(axis.text.x = element_text(angle=90)) + ylim(-3, 6) + scale_x_discrete(limits=c(,,_3Ctrl_Pool, -TARGETplus Non-targeting Control, Non-targeting Control, , , 5, _1, _2, _3, _4, 4K2A_1, 4K2A_2, 4K2A_3, 4K2A_4, 4KA_1, 4KA_2, 4KA_3, 4KA_4, 5K1B_1, 5K1B_2, 5K1B_3, 5K1B_4, 5K1C_1, 5K1C_2, 5K1C_3, 5K1C_4, _1, _2, _3, _4, 3C2A_1, 3C2A_2, 3C2A_3, 3C2A_4))

Mann-Whitney test for significant siRNA treatment effects2

rr siRNA.conditions.for.U.test <- subset(Secondary.siRNA.Screen.Data, siRNA_Target !=  & siRNA_Target !=  & siRNA_Target != _3Ctrl_Pool & siRNA_Target != Non-targeting Control) p_values <- c() for (i in 1:length(unique(siRNA.conditions.for.U.test\(siRNA_Target))){ for (j in 1:length(unique(siRNA.conditions.for.U.test\)siRNA_Target))){ siRNA_Target_1 = subset(siRNA.conditions.for.U.test, siRNA.conditions.for.U.test\(siRNA_Target == unique(siRNA.conditions.for.U.test\)siRNA_Target)[i]) siRNA_Target_1\(siRNA_Target_Number = as.factor(i) siRNA_Target_2 = subset(siRNA.conditions.for.U.test, siRNA.conditions.for.U.test\)siRNA_Target == unique(siRNA.conditions.for.U.test\(siRNA_Target)[j]) siRNA_Target_2\)siRNA_Target_Number = as.factor(j+100) siRNA_Target_Pair = rbind(siRNA_Target_1, siRNA_Target_2) siRNA_Target_Pair_ttest = wilcox.test(Ratio_A.CMAC.to.T.CMAC_mean_intensity.z.score ~ siRNA_Target_Number, data = siRNA_Target_Pair)\(p.value p_values = rbind(p_values, siRNA_Target_Pair_ttest) } } p_values <- as.vector(p_values) p_value_matrix <- matrix(p_values,nrow = length(unique(siRNA.conditions.for.U.test\)siRNA_Target)),ncol = length(unique(siRNA.conditions.for.U.test\(siRNA_Target))) columns <- as.vector(unique(siRNA.conditions.for.U.test\)siRNA_Target)) rows <- as.vector(unique(siRNA.conditions.for.U.test\(siRNA_Target)) p_value_dataframe <- as.data.frame(p_value_matrix, row.names = rows) names(p_value_dataframe) <- columns # print(p_value_dataframe) # Introduce Holm (also called Holm-Bonferroni) p-value correction (used because it gives same stringency against false positives (type 1 errors) with lower probability of false negatives (type 2 errors))) corrected_p_values <- p.adjust(p_values, method = \holm\, n = length(p_values)) corrected_p_value_matrix9 <- matrix(corrected_p_values,nrow = length(unique(siRNA.conditions.for.U.test\)siRNA_Target)),ncol = length(unique(siRNA.conditions.for.U.test\(siRNA_Target))) columns <- as.vector(unique(siRNA.conditions.for.U.test\)siRNA_Target)) rows <- as.vector(unique(siRNA.conditions.for.U.test$siRNA_Target)) corrected_p_value_dataframe <- as.data.frame(corrected_p_value_matrix9, row.names = rows) names(corrected_p_value_dataframe) <- columns print(corrected_p_value_dataframe)

Plot heatmap of corrected p_values2

rr heatmap.2(log(corrected_p_value_matrix9), dendrogram = ‘none’, Rowv = FALSE, Colv = FALSE, labRow = rows, labCol = columns, srtCol = 45, cexRow = 1, cexCol = 1, margins = c(7, 9), symm = TRUE, revC = FALSE, breaks = c(log(1e-300), log(1e-50), log(1e-10), log(1e-6), log(0.001), log(0.01), log(0.05), log(1)), rowsep = 1:nrow(corrected_p_value_matrix9), colsep = 1:ncol(corrected_p_value_matrix9), sepcolor = ‘darkgrey’, sepwidth = c(0.02,0.02), trace = ‘none’, col = c(, , , , , , ), denscol = NULL, keysize = 1.5, key.title = NA)

LS0tCnRpdGxlOiAiU3RhdGlzdGljYWwgQW5hbHN5c2VzIENvZGUgTG9jayBldCBhbCBOQ0IgMjAxOCIKYXV0aG9yOiAiTG9jayBldCBhbCIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogIGh0bWxfZG9jdW1lbnQ6CiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgcGRmX2RvY3VtZW50OgogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRvYzogeWVzCiAgd29yZF9kb2N1bWVudDoKICAgIHRvYzogeWVzCmFsd2F5c19hbGxvd19odG1sOiB5ZXMKLS0tCgoqKgoKKipUaGlzIFIgbWFya2Rvd24gZG9jdW1lbnQgKC5SbWQpIGNvbnRhaW5zIGFuYWx5c2lzLCB2aXN1YWxpc2F0aW9uIGFuZCBzdGF0aXN0aWNhbCB0ZXN0aW5nIHJlbGF0aW5nIHRvIHJlc2VhcmNoIHBhcGVyICJSZXRpY3VsYXIgYWRoZXNpb25zIG1lZGlhdGUgY2VsbC1tYXRyaXggYXR0YWNobWVudCBkdXJpbmcgbWl0b3Npc+KAnSBieSBMb2NrIGV0IGFsIChOQ0IsIDIwMTgpLioqIAoKKipUaGlzIGNvZGUgdXNlcyB0aGUgUiBtYXJrZG93biBmcmFtZXdvcmsgYW5kIGVuYWJsZXMgcHJvZHVjdGlvbiBvZiBzdGF0aXN0aWNhbCBhbmQgZ3JhcGhpY2FsIG91dHB1dHMgZXF1aXZhbGVudCB0byB0aG9zZSBwcmVzZW50ZWQgaW4gdGhlIHBhcGVyLiBTb21lIHB1cmVseSBhZXN0aGV0aWMgZGlmZmVyZW5jZXMgZXhpc3QgdG8gZmluYWwgcGFwZXIgZmlndXJlcyBnaXZlbiBzdWJzZXF1ZW50IGVkaXRpbmcgKGFkb2JlIGlsbHVzdHJhdG9yKSBmb3IgZmlndXJlIGVtYmVkZGluZy4gQWxsIFIgcGFja2FnZXMgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIGNvZGUgd2lsbCBiZSBpbnN0YWxsZWQgYXV0b21hdGljYWxseSB1cG9uIHJ1bm5pbmcgdGhpcyBjb2RlLioqCgoqKlRoaXMgY29kZSBjYWxscyB0aGUgc291cmNlIGRhdGEgZmlsZSBuYW1lZCAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIgYW5kIHNlbGVjdHMgaW5kaXZpZHVhbCBkYXRhIHNoZWV0cyBwZXJ0aW5lbnQgdG8gZWFjaCBhbmFseXNpcy4gVGhlc2Ugc2hlZXRzIGFyZSBuYW1lZCBhY2NvcmRpbmcgdGhlIEZpZ3VyZSBQYW5lbCB0aGF0IHRoZXkgdW5kZXJwaW4uIFRoZSB1c2VyIG11c3QgcGxhY2UgdGhpcyBzb3VyY2UgZGF0YSBmaWxlIGluIGEgbG9jYXRpb24gb2YgdGhlaXIgY2hvaWNlIGFuZCBtb2RpZnkgdGhlICJkYXRhX2lucHV0X3BhdGgiIHZhcmlhYmxlIHRvIHJlZmxlY3QgdGhpcyBsb2NhdGlvbi4gR3JhcGhpY2FsIG91dHB1dHMgYXJlIHNhdmVkIGFjY29yZGluZyB0byB0aGUgcmVsZXZhbnQgRmlndXJlIFBhbmVsIG5hbWVzICh3aXRoIHNvbWUgYWRkaXRpb25hbCBkZXNjcmlwdGl2ZSBpbmZvcm1hdGlvbikgdG8gYSBsb2NhdGlvbiBkZWZpbmVkIGJ5IHRoZSB2YXJpYWJsZSAicGFuZWxfb3V0cHV0X3BhdGgiLiBCeSBkZWZhdWx0IHRoaXMgaXMgaW4gYSBmb2xkZXIgbmFtZWQgIkdyYXBoaWNhbF9PdXRwdXRzIiB3aXRoaW4gdGhlIGRlZmluZWQgImRhdGFfaW5wdXRfcGF0aCIuIE5vdGUgdGhhdCBzb21lIGZpZ3VyZSBwYW5lbHMgd2VyZSBnZW5lcmF0ZWQgZGlyZWN0bHkgd2l0aGluIEV4Y2VsIGFuZCB0aGVzZSBjYW4gYmUgZm91bmQgd2l0aGluIHRoZSBzb3VyY2UgZGF0YSBmaWxlLioqCgoqKkluIGFkZGl0aW9uIHRvIHNwZWNpZmljIC5zdmcgZ3JhcGhpY2FsIG91dHB1dHMsIHRoaXMgUiBtYXJrZG93biBjb2RlIHdpbGwgcHJvZHVjZSBhbiBIVE1MIG5vdGVib29rIHRoYXQgaXMgdXNlZnVsIHRvIGNvbGxlY3RpdmVseSBwcmV2aWV3IGFuZCBlZmZpY2llbnRseSBzaGFyZSBvdXRwdXRzIGFuZCB0aGVpciB1bmRlcmx5aW5nIGNvZGUuIFRoaXMgb3V0cHV0IEhUTUwgbm90ZWJvb2sgZmlsZSBtYXRjaGVzIHRoZSBuYW1lIG9mIHRoaXMgc291cmNlIC5SbWQgZmlsZSwgaS5lLiAiU3RhdGlzdGljYWxfQW5hbHlzaXNfQ29kZV9Mb2NrX2V0X2FsX05DQl8yMDE4Lm5iLmh0bWwiLioqIAoKKioKCgojIFNldHVwCmBgYHtyIGxpYnJhcmllcyBhbmQgRW52aXJvbm1lbnQgQ2xlYW4sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgSW5zdGFsbCBhbmQgYXBwbHkgcmVxdWlyZWQgcGFja2FnZXMKCnVzZVBhY2thZ2UgPC0gZnVuY3Rpb24ocCkgCnsKICBpZiAoIWlzLmVsZW1lbnQocCwgaW5zdGFsbGVkLnBhY2thZ2VzKClbLDFdKSkKICAgIGluc3RhbGwucGFja2FnZXMocCwgZGVwID0gVFJVRSkKICByZXF1aXJlKHAsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkKfQoKCnVzZVBhY2thZ2UoJ2JlZXN3YXJtJykKdXNlUGFja2FnZSgnc20nKQp1c2VQYWNrYWdlKCdkcGx5cicpCnVzZVBhY2thZ2UoJ3RpZHl2ZXJzZScpCnVzZVBhY2thZ2UoJ3JlYWR4bCcpCnVzZVBhY2thZ2UoJ2tuaXRyJykKdXNlUGFja2FnZSgnc3ZnbGl0ZScpCnVzZVBhY2thZ2UoJ2dwbG90cycpCnVzZVBhY2thZ2UoJ2dncGxvdDInKQp1c2VQYWNrYWdlKCdIbWlzYycpCnVzZVBhY2thZ2UoJ3pvbycpCnVzZVBhY2thZ2UoJ3RpZHlxdWFudCcpCnVzZVBhY2thZ2UoJ3NwYXRzdGF0JykKdXNlUGFja2FnZSgnZ3JpZEV4dHJhJykKdXNlUGFja2FnZSgnZ3JpZCcpCnVzZVBhY2thZ2UoJ0dHYWxseScpIAoKIyBDbGVhciBhbGwgcHJlLWV4aXN0aW5nIG9iamVjdHMgZnJvbSB0aGUgY3VycmVudCB3b3Jrc3BhY2UKcm0obGlzdCA9IGxzKCkpCgpgYGAKCiMjIElucHV0IFBhdGgKCmBgYHtyIElucHV0IFBhdGh9CiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCgpkYXRhX2lucHV0X3BhdGggPC0gIi4uLi9Tb3VyY2VfRGF0YSIKCiMgbmFtZSBvZiB0aGUgc291cmNlIGRhdGEgZmlsZSB3aGljaCB5b3UgaGF2ZSBwbGFjZWQgaW4gdGhlIGFib3ZlIGxvY2F0aW9uCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCmBgYAoKCiMjIE91dHB1dCBQYXRoCmBgYHtyIE91dHB1dCBQYXRofQojIERlZmluZSBwYW5lbCBvdXRwdXQgcGF0aAoKcGFuZWxfb3V0cHV0X3BhdGggPC0gcGFzdGUoZGF0YV9pbnB1dF9wYXRoLCAiR3JhcGhpY2FsX091dHB1dHMvIiwgc2VwID0gIi8iKQoKYGBgCgojIEZpZ3VyZSAxCgojIyBJbXBvcnQgRGF0YSBmb3IgRmlndXJlIDEKYGBge3IgbXBvcnQgRGF0YSBmb3IgRmlndXJlIDF9CgojIEltcG9ydCBpbmRpdmlkdWFsIGRhdGEgZmlsZXMKTWFzcy5TcGVjLkRhdGEgPC0gcmVhZF94bHN4KHBhc3RlKGRhdGFfaW5wdXRfcGF0aCwgZGF0YV9maWxlLCBzZXAgPSAiLyIpLCBzaGVldCA9ICJGaWcxQSIsIGNvbF9uYW1lcyA9IFRSVUUpCgpiNS5pbnQudnMuVk4uY29uYyA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzFHIiwgY29sX25hbWVzID0gVFJVRSkKCgpgYGAKCiMjIE1hc3MgU3BlYyBvZiBJbnRlZ3JpbiBzdWJ1bml0cyBpbiBsb25nLXRlcm0gY3VsdHVyZQojIyMgRmlndXJlIDFBIGJveHBsb3Qgb2YgSW50ZWdyaW4gc3VidW5pdHMgc3BlY3RyYWwgY291bnRzCmBgYHtyIEZpZ3VyZSAxQSBib3hwbG90IG9mIEludGVncmluIHN1YnVuaXRzIHNwZWN0cmFsIGNvdW50c30KCiNkZWZpbmUgcGFuZWxfZmlsZV9uYW1lCkludGVncmluX1NwZWN0cmFsX0NvdW50c19GaWxlX05hbWUgPC0gIlBhbmVsIDFBIEludGVncmluIFNwZWN0cmFsIENvdW50cyBCb3hwbG90IgoKYm94cGxvdChNZWFuLlNwZWN0cmFsLkNvdW50cyB+IEludGVncmluLlN1YnVuaXQsIGRhdGEgPSBNYXNzLlNwZWMuRGF0YSwgbm90Y2ggPSBGQUxTRSwgdmFyd2lkdGggPSBGQUxTRSwgbGFzPTEsIHlsYWIgPSAiTWVhbiBTcGVjdHJhbCBDb3VudHMiLCBjb2wgPSAiZ3JleSIsIHlsaW0gPSBjKDAsIDUwKSwgb3V0bGluZSA9IEZBTFNFLCBib3hsdHkgPSAwLCB3aGlza2x0eSA9IDAsIHN0YXBsZWx0eSA9IDAsIG1lZGx3ZCA9IDAuNSwgYm94ZmlsbCA9IE5BKQpiZWVzd2FybShNZWFuLlNwZWN0cmFsLkNvdW50cyB+IEludGVncmluLlN1YnVuaXQsIGRhdGEgPSBNYXNzLlNwZWMuRGF0YSwgbWV0aG9kID0gJ2NlbnRlcicsIGFkZCA9IFQsIGNvbCA9ICJyZWQiLCBwY2ggPSAxOSwgY2V4ID0gMC43KQoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgSW50ZWdyaW5fU3BlY3RyYWxfQ291bnRzX0ZpbGVfTmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTgsIGhlaWdodD02KQoKYm94cGxvdChNZWFuLlNwZWN0cmFsLkNvdW50cyB+IEludGVncmluLlN1YnVuaXQsIGRhdGEgPSBNYXNzLlNwZWMuRGF0YSwgbm90Y2ggPSBGQUxTRSwgdmFyd2lkdGggPSBGQUxTRSwgbGFzPTEsIHlsYWIgPSAiTWVhbiBTcGVjdHJhbCBDb3VudHMiLCBjb2wgPSAiZ3JleSIsIHlsaW0gPSBjKDAsIDUwKSwgb3V0bGluZSA9IEZBTFNFLCBib3hsdHkgPSAwLCB3aGlza2x0eSA9IDAsIHN0YXBsZWx0eSA9IDAsIG1lZGx3ZCA9IDAuNSwgYm94ZmlsbCA9IE5BKQpiZWVzd2FybShNZWFuLlNwZWN0cmFsLkNvdW50cyB+IEludGVncmluLlN1YnVuaXQsIGRhdGEgPSBNYXNzLlNwZWMuRGF0YSwgbWV0aG9kID0gJ2NlbnRlcicsIGFkZCA9IFQsIGNvbCA9ICJyZWQiLCBwY2ggPSAxOSwgY2V4ID0gMC43KQoKZGV2Lm9mZigpCgpgYGAKIyMjIyBULXRlc3RpbmcgZm9yIHNwZWN0cmFsIGNvdW50IGRpZmZlcmVuY2VzIGRpZmZlcmVuY2VzCmBgYHtyfQpBVnZzQjEgPC0gc3Vic2V0KE1hc3MuU3BlYy5EYXRhLCBJbnRlZ3Jpbi5TdWJ1bml0ID09ICJJVEdBViIgfCBJbnRlZ3Jpbi5TdWJ1bml0ID09ICJJVEdCMSIpClRfdGVzdF9BVnZzQjEgPC0gdC50ZXN0KE1lYW4uU3BlY3RyYWwuQ291bnRzIH4gSW50ZWdyaW4uU3VidW5pdCwgZGF0YSA9IEFWdnNCMSwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwgcGFpcmVkID0gRkFMU0UpJHAudmFsdWUKClRfdGVzdF9BVnZzQjEKCkI1dnNCMSA8LSBzdWJzZXQoTWFzcy5TcGVjLkRhdGEsIEludGVncmluLlN1YnVuaXQgPT0gIklUR0I1IiB8IEludGVncmluLlN1YnVuaXQgPT0gIklUR0IxIikKVF90ZXN0X0I1dnNCMSA8LSB0LnRlc3QoTWVhbi5TcGVjdHJhbC5Db3VudHMgfiBJbnRlZ3Jpbi5TdWJ1bml0LCBkYXRhID0gQjV2c0IxLCBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiLCBwYWlyZWQgPSBGQUxTRSkkcC52YWx1ZQoKVF90ZXN0X0I1dnNCMQoKYGBgCgoKIyMgSW50ZWdyaW4gaW50ZW5zaXR5IHJlc3BvbnNlcyB0byBWaXRyb25lY3Rpb24gY29uY2VudHJhdGlvbiBpbiB0YWxpbi1wb3NpdGl2ZSBhbmQgdGFsaW4tbmVnYXRpdmUgYWRoZXNpb25zIAoKIyMjIEJveHBsb3Qgb2YgSW50ZWdyaW4gaW50ZW5zaXR5IHZzIFZpdHJvbmVjdGlvbiBjb25jZW50cmF0aW9uIGluIHRhbGluLXBvc2l0aXZlIGFuZCB0YWxpbi1uZWdhdGl2ZSBhZGhlc2lvbnMKYGBge3IgQm94cGxvdCBvZiBJbnRlZ3JpbiBpbnRlbnNpdHkgdnMgVml0cm9uZWN0aW9uIGNvbmNlbnRyYXRpb24gaW4gdGFsaW4tcG9zaXRpdmUgYW5kIHRhbGluLW5lZ2F0aXZlIGFkaGVzaW9uc30KI2RlZmluZSBwYW5lbF9maWxlX25hbWUKYjVfSW50ZW5zaXR5X0ZpbGVfTmFtZSA8LSAiUGFuZWwgMUcgSW50ZWdyaW4gYjUgSW50ZW5zaXR5IgoKbmFtZXMoYjUuaW50LnZzLlZOLmNvbmMpIDwtIGMoIlRhbGluX1Bvc192c19OZWciLCAiQ29uZGl0aW9uIiwgIk1lYW4uaW50ZWdyaW4uYjUuSW50ZW5zaXR5IikKYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZyA8LSByZWNvZGUoYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZywgQXR5cGljYWwgPSAiVGFsaW5fTmVnIikKYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZyA8LSByZWNvZGUoYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZywgdHlwaWNhbCA9ICJUYWxpbl9Qb3MiKQoKCmI1LmludC52cy5WTi5jb25jJEdyb3VwIDwtIHBhc3RlKGI1LmludC52cy5WTi5jb25jJFRhbGluX1Bvc192c19OZWcsIGI1LmludC52cy5WTi5jb25jJENvbmRpdGlvbiwgc2VwID0gIl8iKQpiNS5pbnQudnMuVk4uY29uYyRHcm91cCA8LSBmYWN0b3IoYjUuaW50LnZzLlZOLmNvbmMkR3JvdXAsIGxldmVscyA9IGMoIlRhbGluX1Bvc18xVk4iLCAiVGFsaW5fTmVnXzFWTiIsICJUYWxpbl9Qb3NfM1ZOIiwgIlRhbGluX05lZ18zVk4iLCAiVGFsaW5fUG9zXzEwVk4iLCAiVGFsaW5fTmVnXzEwVk4iKSkKCgpnZ3Bsb3QoZGF0YSA9IGI1LmludC52cy5WTi5jb25jLCBhZXMoeCA9IEdyb3VwLCB5ID0gTWVhbi5pbnRlZ3Jpbi5iNS5JbnRlbnNpdHkpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IFRhbGluX1Bvc192c19OZWcsIHltaW49Li5sb3dlci4uLCB5bWF4PS4udXBwZXIuLiksIG91dGxpZXIuc2hhcGU9TkEsIG5vdGNoID0gVFJVRSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJUYWxpbl9Qb3MiID0gIiM0RjgwQkMiLCAiVGFsaW5fTmVnIiA9ICIjQzA1MDRGIikpICsgdGhlbWVfY2xhc3NpYygpICsgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDUwMCwgMTMwMCkpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIGI1X0ludGVuc2l0eV9GaWxlX05hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD01LCBoZWlnaHQ9OCkKCmdncGxvdChkYXRhID0gYjUuaW50LnZzLlZOLmNvbmMsIGFlcyh4ID0gR3JvdXAsIHkgPSBNZWFuLmludGVncmluLmI1LkludGVuc2l0eSkpICsgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gVGFsaW5fUG9zX3ZzX05lZywgeW1pbj0uLmxvd2VyLi4sIHltYXg9Li51cHBlci4uKSwgb3V0bGllci5zaGFwZT1OQSwgbm90Y2ggPSBUUlVFKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlRhbGluX1BvcyIgPSAiIzRGODBCQyIsICJUYWxpbl9OZWciID0gIiNDMDUwNEYiKSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNTAwLCAxMzAwKSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKZGV2Lm9mZigpCgpgYGAKCiMjIyMgV2lsY294b24gUmFuayBTdW0gdGVzdGluZyBvZiBiNSBpbnRlbnNpdHkgY2hhbmdlcyBnaXZlbiBpbmNyZWFzZWQgVml0cm9uZWN0aW4KYGBge3IgV2lsY294b24gUmFuayBTdW0gdGVzdGluZyBvZiBiNSBpbnRlbnNpdHkgY2hhbmdlcyBnaXZlbiBpbmNyZWFzZWQgVml0cm9uZWN0aW59ClRhbGluUG9zID0gc3Vic2V0KGI1LmludC52cy5WTi5jb25jLCBiNS5pbnQudnMuVk4uY29uYyRUYWxpbl9Qb3NfdnNfTmVnID09ICJUYWxpbl9Qb3MiKQoKVGFsaW5Qb3NfVk4xX3ZzX1ZOMyA8LSBzdWJzZXQoYjUuaW50LnZzLlZOLmNvbmMsIGI1LmludC52cy5WTi5jb25jJFRhbGluX1Bvc192c19OZWcgPT0gIlRhbGluX1BvcyIgJiBiNS5pbnQudnMuVk4uY29uYyRDb25kaXRpb24gPT0gIjFWTiIgfCBiNS5pbnQudnMuVk4uY29uYyRUYWxpbl9Qb3NfdnNfTmVnID09ICJUYWxpbl9Qb3MiICYgYjUuaW50LnZzLlZOLmNvbmMkQ29uZGl0aW9uID09ICIzVk4iICkKVGFsaW5Qb3NfVk4zX3ZzX1ZOMTAgPC0gc3Vic2V0KGI1LmludC52cy5WTi5jb25jLCBiNS5pbnQudnMuVk4uY29uYyRUYWxpbl9Qb3NfdnNfTmVnID09ICJUYWxpbl9Qb3MiICYgYjUuaW50LnZzLlZOLmNvbmMkQ29uZGl0aW9uID09ICIzVk4iIHwgYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZyA9PSAiVGFsaW5fUG9zIiAmIGI1LmludC52cy5WTi5jb25jJENvbmRpdGlvbiA9PSAiMTBWTiIgKQoKTXVfVGVzdF9UYWxpblBvc19WTjFfdnNfVk4zID0gd2lsY294LnRlc3QoTWVhbi5pbnRlZ3Jpbi5iNS5JbnRlbnNpdHkgfiBDb25kaXRpb24sIGRhdGEgPSBUYWxpblBvc19WTjFfdnNfVk4zKSRwLnZhbHVlCk11X1Rlc3RfVGFsaW5Qb3NfVk4zX3ZzX1ZOMTAgPSB3aWxjb3gudGVzdChNZWFuLmludGVncmluLmI1LkludGVuc2l0eSB+IENvbmRpdGlvbiwgZGF0YSA9IFRhbGluUG9zX1ZOM192c19WTjEwKSRwLnZhbHVlCgpUYWxpbk5lZ19WTjFfdnNfVk4zIDwtIHN1YnNldChiNS5pbnQudnMuVk4uY29uYywgYjUuaW50LnZzLlZOLmNvbmMkVGFsaW5fUG9zX3ZzX05lZyA9PSAiVGFsaW5fTmVnIiAmIGI1LmludC52cy5WTi5jb25jJENvbmRpdGlvbiA9PSAiMVZOIiB8IGI1LmludC52cy5WTi5jb25jJFRhbGluX1Bvc192c19OZWcgPT0gIlRhbGluX05lZyIgJiBiNS5pbnQudnMuVk4uY29uYyRDb25kaXRpb24gPT0gIjNWTiIgKQpUYWxpbk5lZ19WTjNfdnNfVk4xMCA8LSBzdWJzZXQoYjUuaW50LnZzLlZOLmNvbmMsIGI1LmludC52cy5WTi5jb25jJFRhbGluX1Bvc192c19OZWcgPT0gIlRhbGluX05lZyIgJiBiNS5pbnQudnMuVk4uY29uYyRDb25kaXRpb24gPT0gIjNWTiIgfCBiNS5pbnQudnMuVk4uY29uYyRUYWxpbl9Qb3NfdnNfTmVnID09ICJUYWxpbl9OZWciICYgYjUuaW50LnZzLlZOLmNvbmMkQ29uZGl0aW9uID09ICIxMFZOIiApCgpNdV9UZXN0X1RhbGluTmVnX1ZOMV92c19WTjMgPSB3aWxjb3gudGVzdChNZWFuLmludGVncmluLmI1LkludGVuc2l0eSB+IENvbmRpdGlvbiwgZGF0YSA9IFRhbGluTmVnX1ZOMV92c19WTjMpJHAudmFsdWUKTXVfVGVzdF9UYWxpbk5lZ19WTjNfdnNfVk4xMCA9IHdpbGNveC50ZXN0KE1lYW4uaW50ZWdyaW4uYjUuSW50ZW5zaXR5IH4gQ29uZGl0aW9uLCBkYXRhID0gVGFsaW5OZWdfVk4zX3ZzX1ZOMTApJHAudmFsdWUKCmBgYAoKIyBGaWd1cmUgMgoKIyMgSW1wb3J0IERhdGEgZm9yIEZpZ3VyZSAyCmBgYHtyIG1wb3J0IERhdGEgZm9yIEZpZ3VyZSAyfQoKIyBTZXQgeW91ciBwYXRoIHRvIGlucHV0IGRhdGEKZGF0YV9pbnB1dF9wYXRoIDwtICIvVXNlcnMvam9obmxvY2svRHJvcGJveC9BLUNNQUMgTWFuY2hlc3RlciBjb2xsYWJvcmF0aW9uL05DQiBzdWJtaXNzaW9uIGRvY3VtZW50cy9SZXN1Ym1pc3Npb24gMi9Tb3VyY2VfRGF0YSIKZGF0YV9maWxlIDwtICJTdXBwbGVtZW50YXJ5IFRhYmxlIDEgU3RhdGlzdGljcyBTb3VyY2UgRGF0YS54bHN4IgoKIyBJbXBvcnQgaW5kaXZpZHVhbCBkYXRhIGZpbGVzCkZSQVAuZGF0YSA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzJTX1QiLCBjb2xfbmFtZXMgPSBUUlVFKQoKU1RPUk0uRGF0YSA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzJWX1ciLCBjb2xfbmFtZXMgPSBUUlVFKQoKYGBgCgojIyBBbmFseXNpcyBvZiBpbnRlZ3JpbiBiNSBGUkFQIHJlY292ZXJ5IGN1cnZlcyBpbiBSZXRpY3VsYXIgYW5kIEZvY2FsIGFkaGVzaW9ucwoKIyMjIEludGVncmluIGI1IEZSQVAgYW5hbHlzaXMgY29tcGFyaW5nIFJldGljdWxhciBhbmQgRm9jYWwgYWRoZXNpb25zCmBgYHtyIEludGVncmluIGI1IEZSQVAgYW5hbHlzaXMgY29tcGFyaW5nIFJldGljdWxhciBhbmQgRm9jYWwgYWRoZXNpb25zfQojZGVmaW5lIHBhbmVsX2ZpbGVfbmFtZQpGUkFQX0N1cnZlX0ZpbGVfTmFtZSA8LSAiUGFuZWwgMlMgYjUgRlJBUCByZWNvdmVyeSIKCm5hbWVzKEZSQVAuZGF0YSkgPC0gYygiU3RhbmRhcmRpc2VkX2I1X0ZSQVBfcmVjb3ZlcnlfcmVsYXRpdmVfdG9fcHJlYmxlYWNoIiwgIlRpbWUiLCAiQmxlYWNoX1JPSSIsICJSZXRpY3VsYXJfdnNfRm9jYWwiKQpGUkFQLmRhdGEkUmV0aWN1bGFyX3ZzX0ZvY2FsIDwtIHJlY29kZShGUkFQLmRhdGEkUmV0aWN1bGFyX3ZzX0ZvY2FsLCBhdHlwaWNhbCA9ICJSZXRpY3VsYXIiKQpGUkFQLmRhdGEkUmV0aWN1bGFyX3ZzX0ZvY2FsIDwtIHJlY29kZShGUkFQLmRhdGEkUmV0aWN1bGFyX3ZzX0ZvY2FsLCB0eXBpY2FsID0gIkZvY2FsIikKCgpnZ3Bsb3QoZGF0YT1GUkFQLmRhdGEsIGFlcyh4PVRpbWUsIHk9U3RhbmRhcmRpc2VkX2I1X0ZSQVBfcmVjb3ZlcnlfcmVsYXRpdmVfdG9fcHJlYmxlYWNoLCBjb2xvdXIgPSBSZXRpY3VsYXJfdnNfRm9jYWwpLCBhbHBoYSA9IDAuMSkgKwogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9Im1lYW5fY2xfbm9ybWFsIiwgYWxwaGEgPSAwLjUpICsgdGhlbWVfY2xhc3NpYygpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJSZXRpY3VsYXIiID0gIiNCRjRDNDkiLCAiRm9jYWwiID0gIiM0QjdGQkIiKSkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMC4yLCBzaXplID0gMSwgZmlsbCA9ICIjM0EzQTNBIikKCgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBGUkFQX0N1cnZlX0ZpbGVfTmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTYsIGhlaWdodD00KQoKZ2dwbG90KGRhdGE9RlJBUC5kYXRhLCBhZXMoeD1UaW1lLCB5PVN0YW5kYXJkaXNlZF9iNV9GUkFQX3JlY292ZXJ5X3JlbGF0aXZlX3RvX3ByZWJsZWFjaCwgY29sb3VyID0gUmV0aWN1bGFyX3ZzX0ZvY2FsKSwgYWxwaGEgPSAwLjEpICsKICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSJtZWFuX2NsX25vcm1hbCIsIGFscGhhID0gMC41KSArIHRoZW1lX2NsYXNzaWMoKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiUmV0aWN1bGFyIiA9ICIjQkY0QzQ5IiwgIkZvY2FsIiA9ICIjNEI3RkJCIikpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc3BhbiA9IDAuMiwgc2l6ZSA9IDEsIGZpbGwgPSAiIzNBM0EzQSIpCgpkZXYub2ZmKCkKCmBgYAoKIyMjIEtTIHRlc3Qgb2YgRlJBUCByZWNvdmVyeSBjdXJ2ZXMKYGBge3IgS1MgdGVzdCBvZiBGUkFQIHJlY292ZXJ5IGN1cnZlc30KUmV0aWN1bGFyLkZSQVAuZGF0YSA8LSBzdWJzZXQoRlJBUC5kYXRhLCBSZXRpY3VsYXJfdnNfRm9jYWwgPT0gIlJldGljdWxhciIpCkZvY2FsLkZSQVAuZGF0YSA8LSBzdWJzZXQoRlJBUC5kYXRhLCBSZXRpY3VsYXJfdnNfRm9jYWwgPT0gIkZvY2FsIikKClJldGljdWxhci5GUkFQLmRhdGEuTE9FU1MgPC0gbG9lc3MoU3RhbmRhcmRpc2VkX2I1X0ZSQVBfcmVjb3ZlcnlfcmVsYXRpdmVfdG9fcHJlYmxlYWNoIH4gVGltZSwgZGF0YSA9IFJldGljdWxhci5GUkFQLmRhdGEsIHNwYW4gPSAwLjIpCkZvY2FsLkZSQVAuZGF0YS5MT0VTUyA8LSBsb2VzcyhTdGFuZGFyZGlzZWRfYjVfRlJBUF9yZWNvdmVyeV9yZWxhdGl2ZV90b19wcmVibGVhY2ggfiBUaW1lLCBkYXRhID0gRm9jYWwuRlJBUC5kYXRhLCBzcGFuID0gMC4yKQoKUmV0aWN1bGFyLkZSQVAuZGF0YS5MT0VTUy5zaW5ndWxhciA8LSB1bmlxdWUoUmV0aWN1bGFyLkZSQVAuZGF0YS5MT0VTUyRmaXR0ZWQpCkZvY2FsLkZSQVAuZGF0YS5MT0VTUy5zaW5ndWxhciA8LSB1bmlxdWUoRm9jYWwuRlJBUC5kYXRhLkxPRVNTJGZpdHRlZCkKCktTLlJldGljdWxhci52cy5Gb2NhbC5GUkFQIDwtIGtzLnRlc3QoUmV0aWN1bGFyLkZSQVAuZGF0YS5MT0VTUy5zaW5ndWxhciwgRm9jYWwuRlJBUC5kYXRhLkxPRVNTLnNpbmd1bGFyLCBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiKQoKcHJpbnQoS1MuUmV0aWN1bGFyLnZzLkZvY2FsLkZSQVAkcC52YWx1ZSkKYGBgCgojIyBBbmFseXNpcyBvZiBpbnRlcnBoYXNlIFNUT1JNIGRhdGEKCiMjIyBTVE9STSBkYXRhIHdyYW5nbGluZzEKYGBge3IgU1RPUk0gZGF0YSB3cmFuZ2xpbmcxfQojIyBEZXRlcm1pbmUgQ01BQy50eXBlIChSZXRpY3VsYXIgdnMgRm9jYWwgZGVwZW5kaW5nIG9uIHByZXNlbmNlIG9mIEEgaW4gJEZpbGUgKGNvbHVtbikpCgpDTUFDLnR5cGUgPSBjKCkKZm9yIChjbHVzdGVyIGluIDE6bGVuZ3RoKFNUT1JNLkRhdGEkRmlsZSkgKSB7CiAgQ01BQy50eXBlW2NsdXN0ZXJdIDwtIGlmKGdyZXBsKCJBIiwgU1RPUk0uRGF0YSRGaWxlW2NsdXN0ZXJdKSA9PSBUUlVFKSB7CiAgICAiUmV0aWN1bGFyIgogIH0gZWxzZSBpZihncmVwbCgiVCIsIFNUT1JNLkRhdGEkRmlsZVtjbHVzdGVyXSkgPT0gVFJVRSkgewogICAgIkZvY2FsIgogIH0gZWxzZSBpZihncmVwbCgiTlIiLCBTVE9STS5EYXRhJEZpbGVbY2x1c3Rlcl0pID09IFRSVUUpIHsKICAgICJOb24tUmV0cmFjdGlvbiIKICB9IGVsc2UgewogICAgIlJldHJhY3Rpb24iCiAgfQp9CgpTVE9STS5EYXRhJENNQUMudHlwZSA8LSBjYmluZChhcy5jaGFyYWN0ZXIoQ01BQy50eXBlKSkKCiMjIFVuaXF1ZSBuYW5vY2x1c3RlciBJRCBnZW5lcmF0aW9uID0gbWVyZ2Ugb2YgRm9sZGVyLCBGaWxlIGFuZCBDbHVzdGVyCgojIFNUT1JNLkRhdGEkVW5pcXVlLm5jSUQgPC0gYXMuZmFjdG9yKHBhc3RlKFNUT1JNLkRhdGEkRm9sZGVyLCBTVE9STS5EYXRhJEZpbGUsIFNUT1JNLkRhdGEkQ2x1c3RlcikpClNUT1JNLkRhdGEkVW5pcXVlLkNNQUNJRCA8LSBhcy5mYWN0b3IocGFzdGUoU1RPUk0uRGF0YSRGb2xkZXIsIFNUT1JNLkRhdGEkRmlsZSkpClNUT1JNLkRhdGEgPC0gYXMuZGF0YS5mcmFtZShTVE9STS5EYXRhKQpgYGAKCiMjIyBOZWFyZXN0IE5laWdoYm91ciBBbmFseXNpcyBiZXR3ZWVuIGxvY2FsaXNhdGlvbnMgd2l0aGluIHVuaXF1ZSBuYW5vY2x1c3RlcnMKYGBge3IgTmVhcmVzdCBOZWlnaGJvdXIgQW5hbHlzaXMgYmV0d2VlbiBsb2NhbGlzYXRpb25zIHdpdGhpbiB1bmlxdWUgbmFub2NsdXN0ZXJzfQojIyBOTkQgYW5hbHlzaXMgb2YgSW5jaXRlMyBkYXRhCgpOTk5EIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgodW5pcXVlKFNUT1JNLkRhdGEkVW5pcXVlLkNNQUNJRCkpICkgewogIHRlbXAgPSBTVE9STS5EYXRhW1NUT1JNLkRhdGEkVW5pcXVlLkNNQUNJRCA9PSB1bmlxdWUoU1RPUk0uRGF0YSRVbmlxdWUuQ01BQ0lEKVtpXSwgXQogIE5OTkQgPSBhcHBlbmQoTk5ORCwgbm5kaXN0KHRlbXBbLDddLCB0ZW1wWyw4XSwgaz0xKSkKfQoKU1RPUk0uRGF0YSROTk5EIDwtIGNiaW5kKE5OTkQpCmBgYAoKIyMjIEJveHBsb3RzIHN1bW1hcmlzaW5nIE5lYXJlc3QgTmVpZ2hib3V0IERpc3RhbmNlIHBlciBuYW5vY2x1c3RlcgpgYGB7ciBCb3hwbG90cyBzdW1tYXJpc2luZyBOZWFyZXN0IE5laWdoYm91dCBEaXN0YW5jZSBwZXIgbmFub2NsdXN0ZXJ9Ck5OTkQuYm94cGxvdC5maWxlbmFtZSA8LSAiUGFuZWwgMlYgbmVhcmVzdCBuZWlnaGJvdXIgYm94cGxvdCIKCk5OTkQuQSA9IHN1YnNldChTVE9STS5EYXRhJE5OTkQsIENNQUMudHlwZSA9PSAiUmV0aWN1bGFyIikKCk5OTkQuVCA9IHN1YnNldChTVE9STS5EYXRhJE5OTkQsIENNQUMudHlwZSA9PSAiRm9jYWwiKQoKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIE5OTkQuYm94cGxvdC5maWxlbmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTYsIGhlaWdodD00KQoKYm94cGxvdChOTk5EIH4gQ01BQy50eXBlLCBzdWJzZXQoU1RPUk0uRGF0YSwgQ01BQy50eXBlID09ICJSZXRpY3VsYXIiIHwgQ01BQy50eXBlID09ICJGb2NhbCIpLCBub3RjaCA9IFRSVUUsIG91dGxpbmUgPSBGQUxTRSwKICAgICAgICBtYWluID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIG9mIE5hbm9jbHVzdGVyIGJ5IENNQUMgVHlwZSIsCiAgICAgICAgeGxhYiA9ICJDTUFDIHR5cGUiLCAKICAgICAgICB5bGFiID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIChubSkiLAogICAgICAgIHBsb3QgPSAiVFJVRSIKKQoKZGV2Lm9mZigpCgpib3hwbG90KE5OTkQgfiBDTUFDLnR5cGUsIHN1YnNldChTVE9STS5EYXRhLCBDTUFDLnR5cGUgPT0gIlJldGljdWxhciIgfCBDTUFDLnR5cGUgPT0gIkZvY2FsIiksIG5vdGNoID0gVFJVRSwgb3V0bGluZSA9IEZBTFNFLAogICAgICAgIG1haW4gPSAiTmVhcmVzdCBOZWlnaGJvdXIgRGlzdGFuY2Ugb2YgTmFub2NsdXN0ZXIgYnkgQ01BQyBUeXBlIiwKICAgICAgICB4bGFiID0gIkNNQUMgdHlwZSIsIAogICAgICAgIHlsYWIgPSAiTmVhcmVzdCBOZWlnaGJvdXIgRGlzdGFuY2UgKG5tKSIsCiAgICAgICAgcGxvdCA9ICJUUlVFIgopCgpgYGAKCiMjIyBCb3hwbG90cyBzdW1tYXJpc2luZyBNb2xlY3VsYXIgTG9jYWxpemF0aW9uIHBlciBuYW5vY2x1c3RlcgpgYGB7ciBCb3hwbG90cyBzdW1tYXJpc2luZyBNb2xlY3VsYXIgTG9jYWxpemF0aW9uIHBlciBuYW5vY2x1c3Rlcn0KTW9sZWN1bGUubnVtYmVyLmJveHBsb3QuZmlsZW5hbWUgPC0gIlBhbmVsIDJXIG1vbGVjdWxhciBudW1iZXIgYm94cGxvdCIKCk1vbGVjdWxlcy5BID0gYXMubnVtZXJpYyhzdWJzZXQoU1RPUk0uRGF0YSRNb2xlY3VsZXMsIENNQUMudHlwZSA9PSAiUmV0aWN1bGFyIikpCgpNb2xlY3VsZXMuVCA9IGFzLm51bWVyaWMoc3Vic2V0KFNUT1JNLkRhdGEkTW9sZWN1bGVzLCBDTUFDLnR5cGUgPT0gIkZvY2FsIikpCgoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgTW9sZWN1bGUubnVtYmVyLmJveHBsb3QuZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD02LCBoZWlnaHQ9NCkKCmJveHBsb3QoYXMubnVtZXJpYyhNb2xlY3VsZXMpIH4gQ01BQy50eXBlLCBzdWJzZXQoU1RPUk0uRGF0YSwgQ01BQy50eXBlID09ICJSZXRpY3VsYXIiIHwgQ01BQy50eXBlID09ICJGb2NhbCIpLCBub3RjaCA9IFRSVUUsIG91dGxpbmUgPSBGQUxTRSwKICAgICAgICBtYWluID0gIk51bWJlciBvZiBJbnRlZ3JpbiBhdmI1IE1vbGVjdWxlcyBieSBDTUFDIFR5cGUiLAogICAgICAgIHhsYWIgPSAiQ01BQyB0eXBlIiwgCiAgICAgICAgeWxhYiA9ICJOdW1iZXIgb2YgSW50ZWdyaW4gYXZiNSBNb2xlY3VsZXMiLAogICAgICAgIHBsb3QgPSAiVFJVRSIKICAgICAgICApCgpkZXYub2ZmKCkKCmJveHBsb3QoYXMubnVtZXJpYyhNb2xlY3VsZXMpIH4gQ01BQy50eXBlLCBzdWJzZXQoU1RPUk0uRGF0YSwgQ01BQy50eXBlID09ICJSZXRpY3VsYXIiIHwgQ01BQy50eXBlID09ICJGb2NhbCIpLCBub3RjaCA9IFRSVUUsIG91dGxpbmUgPSBGQUxTRSwKICAgICAgICBtYWluID0gIk51bWJlciBvZiBJbnRlZ3JpbiBhdmI1IE1vbGVjdWxlcyBieSBDTUFDIFR5cGUiLAogICAgICAgIHhsYWIgPSAiQ01BQyB0eXBlIiwgCiAgICAgICAgeWxhYiA9ICJOdW1iZXIgb2YgSW50ZWdyaW4gYXZiNSBNb2xlY3VsZXMiLAogICAgICAgIHBsb3QgPSAiVFJVRSIKICAgICAgICApCgpgYGAKCiMgRmlndXJlIDMKCiMjIEltcG9ydCBEYXRhIGZvciBGaWd1cmUgMwpgYGB7ciBJbXBvcnQgRGF0YSBmb3IgRmlndXJlIDN9CiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCmRhdGFfaW5wdXRfcGF0aCA8LSAiL1VzZXJzL2pvaG5sb2NrL0Ryb3Bib3gvQS1DTUFDIE1hbmNoZXN0ZXIgY29sbGFib3JhdGlvbi9OQ0Igc3VibWlzc2lvbiBkb2N1bWVudHMvUmVzdWJtaXNzaW9uIDIvU291cmNlX0RhdGEiCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCiMgSW1wb3J0IGluZGl2aWR1YWwgZGF0YSBmaWxlcwoKQ3l0b0QyaF92c19jb250cm9sIDwtIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiRmlnM0MiLCBjb2xfbmFtZXMgPSBUUlVFKQpDeXRvRDJoX3ZzX2NvbnRyb2wgPC0gQ3l0b0QyaF92c19jb250cm9sWywxOjNdCgpBZGhlc2lvbi5Bc3NheS5EYXRhIDwtIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiRmlnM0UiLCBjb2xfbmFtZXMgPSBUUlVFKQpBZGhlc2lvbi5Bc3NheS5EYXRhIDwtIEFkaGVzaW9uLkFzc2F5LkRhdGFbLDE6NF0KClRhbGluLktELkRhdGEgPC0gcmVhZF94bHN4KHBhc3RlKGRhdGFfaW5wdXRfcGF0aCwgZGF0YV9maWxlLCBzZXAgPSAiLyIpLCBzaGVldCA9ICJGaWczSF9JIiwgY29sX25hbWVzID0gVFJVRSkKCmBgYAoKIyMgQWRoZXNpb24gQXNzYXkKIyMjIEZpZyAzRSBQbG90IEFkaGVzaW9uIExldmVscyBwZXIgQ29uZGl0aW9uCmBgYHtyIFBsb3QgQWRoZXNpb24gTGV2ZWxzIHBlciBDb25kaXRpb259Cm9sZHBhciA8LSBwYXIoKQpwYXIobWFyID0gYygxMCwgMi41LCAxLCAxKSkKCiNkZWZpbmUgcGFuZWxfZmlsZV9uYW1lCkFkaGVzaW9uX0Fzc2F5X3BhbmVsX2ZpbGVfbmFtZSA8LSAiUGFuZWwgM0UgQWRoZXNpb24gQXNzYXkgQm94cGxvdHMiCgpBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbiA8LSBmYWN0b3IoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24sIHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpCgptYXhfYWRoZXNpb24gPC0gbWF4KEFkaGVzaW9uLkFzc2F5LkRhdGEkTnVtYmVyT2JqZWN0cykKQWRoZXNpb24uQXNzYXkuRGF0YSROb3JtYWxpc2VkX0FkaGVzaW9uIDwtIEFkaGVzaW9uLkFzc2F5LkRhdGEkTnVtYmVyT2JqZWN0cy9tYXhfYWRoZXNpb24KCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIEFkaGVzaW9uX0Fzc2F5X3BhbmVsX2ZpbGVfbmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTcuNywgaGVpZ2h0PTYuNSkKCmJveHBsb3QoTm9ybWFsaXNlZF9BZGhlc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IEFkaGVzaW9uLkFzc2F5LkRhdGEsIG5vdGNoID0gRkFMU0UsIHZhcndpZHRoID0gRkFMU0UsIG91dGxpbmUgPSBGLCBsYXM9MiwgeWxhYiA9ICJSZWxhdGl2ZSBDZWxsIE51bWJlciIsIGNvbCA9IGMoImNzMXd0IC1DeXRvIiA9ICIjQ0IyMzI3IiwgImNzMXd0ICtDeXRvICtSR0QiID0gIiNDQjIzMjciLCAiY3MxYjUgLUN5dG8iID0gIiM0Nzc1QTMiLCAiY3MxYjUgLUN5dG8gK1JBRCIgPSAiIzQ3NzVBMyIsICJjczFiNSAtQ3l0byArUkdEIiA9ICIjOUVDMEU1IiwgImNzMWI1ICtDeXRvIiA9ICIjNDc3NUEzIiwgImNzMWI1ICtDeXRvICtSQUQiID0gIiM0Nzc1QTMiLCAiY3MxYjUgK0N5dG8gK1JHRCIgPSAiIzlFQzBFNSIpLCB5bGltID0gYygwLDEuMikpCmJlZXN3YXJtKE5vcm1hbGlzZWRfQWRoZXNpb24gfiBDb25kaXRpb24sIGRhdGEgPSBBZGhlc2lvbi5Bc3NheS5EYXRhLCBtZXRob2QgPSAnY2VudGVyJywgYWRkID0gVCwgY29sID0gImxpZ2h0Z3JleSIsIHBjaCA9IDE5LCBjZXggPSAwLjcpCgpkZXYub2ZmKCkKCmJveHBsb3QoTm9ybWFsaXNlZF9BZGhlc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IEFkaGVzaW9uLkFzc2F5LkRhdGEsIG5vdGNoID0gRkFMU0UsIHZhcndpZHRoID0gRkFMU0UsIG91dGxpbmUgPSBGLCBsYXM9MiwgeWxhYiA9ICJSZWxhdGl2ZSBDZWxsIE51bWJlciIsIGNvbCA9IGMoImNzMXd0IC1DeXRvIiA9ICIjQ0IyMzI3IiwgImNzMXd0ICtDeXRvICtSR0QiID0gIiNDQjIzMjciLCAiY3MxYjUgLUN5dG8iID0gIiM0Nzc1QTMiLCAiY3MxYjUgLUN5dG8gK1JBRCIgPSAiIzQ3NzVBMyIsICJjczFiNSAtQ3l0byArUkdEIiA9ICIjOUVDMEU1IiwgImNzMWI1ICtDeXRvIiA9ICIjNDc3NUEzIiwgImNzMWI1ICtDeXRvICtSQUQiID0gIiM0Nzc1QTMiLCAiY3MxYjUgK0N5dG8gK1JHRCIgPSAiIzlFQzBFNSIpLCB5bGltID0gYygwLDEuMikpCmJlZXN3YXJtKE5vcm1hbGlzZWRfQWRoZXNpb24gfiBDb25kaXRpb24sIGRhdGEgPSBBZGhlc2lvbi5Bc3NheS5EYXRhLCBtZXRob2QgPSAnY2VudGVyJywgYWRkID0gVCwgY29sID0gImxpZ2h0Z3JleSIsIHBjaCA9IDE5LCBjZXggPSAwLjcpCgoKYGBgCgojIyMjIFQtdGVzdGluZyBmb3IgQWRoZXNpb24gTGV2ZWwgZGlmZmVyZW5jZXMgd2l0aCBIb2xtLUJvbmZlcnJvbmkgcC12YWx1ZSBjb3JyZWN0aW9uCmBgYHtyIFQtdGVzdGluZyBmb3IgQWRoZXNpb24gTGV2ZWwgZGlmZmVyZW5jZXMgd2l0aCBIb2xtLUJvbmZlcnJvbmkgcC12YWx1ZSBjb3JyZWN0aW9ufQoKcF92YWx1ZXMgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKSl7CiAgZm9yIChqIGluIDE6bGVuZ3RoKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpKXsKICAgIENvbmRpdGlvbl8xID0gc3Vic2V0KEFkaGVzaW9uLkFzc2F5LkRhdGEsIEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uID09IHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbilbaV0pCiAgICBDb25kaXRpb25fMSRDb25kaXRpb25fTnVtYmVyID0gYXMuZmFjdG9yKGkpCiAgICBDb25kaXRpb25fMiA9IHN1YnNldChBZGhlc2lvbi5Bc3NheS5EYXRhLCBBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbiA9PSB1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pW2pdKQogICAgQ29uZGl0aW9uXzIkQ29uZGl0aW9uX051bWJlciA9IGFzLmZhY3RvcihqKzEwMCkKICAgIENvbmRpdGlvbl9QYWlyID0gcmJpbmQoQ29uZGl0aW9uXzEsIENvbmRpdGlvbl8yKQogICAgQ29uZGl0aW9uX1BhaXJfdHRlc3QgPSB0LnRlc3QoTm9ybWFsaXNlZF9BZGhlc2lvbiB+IENvbmRpdGlvbl9OdW1iZXIsIGRhdGEgPSBDb25kaXRpb25fUGFpciwgcGFpcmVkID0gRkFMU0UpJHAudmFsdWUKICAgIHBfdmFsdWVzID0gcmJpbmQocF92YWx1ZXMsIENvbmRpdGlvbl9QYWlyX3R0ZXN0KQogIH0KfQoKcF92YWx1ZXMgPC0gYXMudmVjdG9yKHBfdmFsdWVzKQoKcF92YWx1ZV9tYXRyaXggPC0gbWF0cml4KHBfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uKSkKcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShwX3ZhbHVlX21hdHJpeCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMocF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCiMgcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgojIEludHJvZHVjZSBIb2xtIChhbHNvIGNhbGxlZCBIb2xtLUJvbmZlcnJvbmkpIHAtdmFsdWUgY29ycmVjdGlvbiAodXNlZCBiZWNhdXNlIGl0IGdpdmVzIHNhbWUgc3RyaW5nZW5jeSBhZ2FpbnN0IGZhbHNlIHBvc2l0aXZlcyAodHlwZSAxIGVycm9ycykgd2l0aCBsb3dlciBwcm9iYWJpbGl0eSBvZiBmYWxzZSBuZWdhdGl2ZXMgKHR5cGUgMiBlcnJvcnMpKSkKCmNvcnJlY3RlZF9wX3ZhbHVlcyA8LSBwLmFkanVzdChwX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iLCBuID0gbGVuZ3RoKHBfdmFsdWVzKSkKCmNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDEgPC0gbWF0cml4KGNvcnJlY3RlZF9wX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpLG5jb2wgPSBsZW5ndGgodW5pcXVlKEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uKSkpCmNvbHVtbnMgPC0gYXMudmVjdG9yKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpCmNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDEsIHJvdy5uYW1lcyA9IHJvd3MpCm5hbWVzKGNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKcHJpbnQoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKQoKYGBgCgojIyBQbG90IGhlYXRtYXAgb2YgY29ycmVjdGVkIHBfdmFsdWVzCmBgYHtyIFBsb3QgaGVhdG1hcCBvZiBjb3JyZWN0ZWQgcF92YWx1ZXMsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTV9CmhlYXRtYXAuMihsb2coY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4MSksIGRlbmRyb2dyYW0gPSAnbm9uZScsIFJvd3YgPSBGQUxTRSwgQ29sdiA9IEZBTFNFLCBsYWJSb3cgPSByb3dzLCBsYWJDb2wgPSBjb2x1bW5zLCBzcnRDb2wgPSA0NSwgY2V4Um93ID0gMSwgY2V4Q29sID0gMSwgbWFyZ2lucyA9IGMoNywgOSksIHN5bW0gPSBUUlVFLCByZXZDID0gRkFMU0UsIGJyZWFrcyA9IGMobG9nKDFlLTMwMCksIGxvZygxZS0xMCksIGxvZygxZS02KSwgbG9nKDAuMDAxKSwgbG9nKDAuMDEpLCBsb2coMC4wNSksIGxvZygxKSksIHJvd3NlcCA9IDE6bnJvdyhjb3JyZWN0ZWRfcF92YWx1ZV9tYXRyaXgxKSwgY29sc2VwID0gMTpuY29sKGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDEpLCBzZXBjb2xvciA9ICdkYXJrZ3JleScsIHNlcHdpZHRoID0gYygwLjAyLDAuMDIpLCB0cmFjZSA9ICdub25lJywgY29sID0gYygicmVkIiwgIm9yYW5nZSIsICJncmVlbiIsICJibHVlIiwgInB1cnBsZSIsICJsaWdodGdyZXkiKSwgZGVuc2NvbCA9IE5VTEwsIGtleXNpemUgPSAxLjUsIGtleS50aXRsZSA9IE5BKQpgYGAKCgojIyMjIFdpbGNveG9uIFJhbmsgU3VtIHRlc3RpbmcgZm9yIEFkaGVzaW9uIExldmVsIGRpZmZlcmVuY2VzCmBgYHtyIFdpbGNveG9uIFJhbmsgU3VtIHRlc3RpbmcgZm9yIEFkaGVzaW9uIExldmVsIGRpZmZlcmVuY2VzfQoKVV92YWx1ZXMgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKSl7CiAgZm9yIChqIGluIDE6bGVuZ3RoKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpKXsKICAgIENvbmRpdGlvbl8xID0gc3Vic2V0KEFkaGVzaW9uLkFzc2F5LkRhdGEsIEFkaGVzaW9uLkFzc2F5LkRhdGEkQ29uZGl0aW9uID09IHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbilbaV0pCiAgICBDb25kaXRpb25fMSRDb25kaXRpb25fTnVtYmVyID0gYXMuZmFjdG9yKGkpCiAgICBDb25kaXRpb25fMiA9IHN1YnNldChBZGhlc2lvbi5Bc3NheS5EYXRhLCBBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbiA9PSB1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pW2pdKQogICAgQ29uZGl0aW9uXzIkQ29uZGl0aW9uX051bWJlciA9IGFzLmZhY3RvcihqKzEwMCkKICAgIENvbmRpdGlvbl9QYWlyID0gcmJpbmQoQ29uZGl0aW9uXzEsIENvbmRpdGlvbl8yKQogICAgQ29uZGl0aW9uX1BhaXJfVXRlc3QgPSB3aWxjb3gudGVzdChOb3JtYWxpc2VkX0FkaGVzaW9uIH4gQ29uZGl0aW9uX051bWJlciwgZGF0YSA9IENvbmRpdGlvbl9QYWlyKSRwLnZhbHVlCiAgICBVX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBDb25kaXRpb25fUGFpcl9VdGVzdCkKICB9Cn0KClVfdmFsdWVzIDwtIGFzLnZlY3RvcihVX3ZhbHVlcykKClVfdmFsdWVfbWF0cml4IDwtIG1hdHJpeChVX3ZhbHVlcywgbnJvdyA9IGxlbmd0aCh1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKSxuY29sID0gbGVuZ3RoKHVuaXF1ZShBZGhlc2lvbi5Bc3NheS5EYXRhJENvbmRpdGlvbikpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKQpyb3dzIDwtIGFzLnZlY3Rvcih1bmlxdWUoQWRoZXNpb24uQXNzYXkuRGF0YSRDb25kaXRpb24pKQpVX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKFVfdmFsdWVfbWF0cml4LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhVX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKcHJpbnQoVV92YWx1ZV9kYXRhZnJhbWUpCgpgYGAKCiMjIFRhbGluIEtEIGVmZmVjdHMKIyMjIFBsb3QgYW5kIHRlc3QgVGFsaW4gS0QgZWZmZWN0cyBvbiBjZWxsIGFyZWEgYW5kIGludGVncmluIGI1IGludGVuc2l0eSB3aXRoaW4gYWRoZXNpb25zCmBgYHtyIGJlZXN3YXJtIHBsb3Qgb2YgdGFsaW4gS0QgZWZmZWN0cyBvbiBjZWxsIHNwcmVhZGluZyBhbmQgYjUgY2x1c3RlcmluZ30KIyBiZWVzd2FybShUb3RhbC5UYWxpbi5wZXIuQ2VsbCB+IHNpUk5BLi5PbGlnbywgZGF0YSA9IFRhbGluLktELkRhdGEsIG1ldGhvZCA9ICdjZW50ZXInLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxOSwgY2V4ID0gMSwgeWxpbSA9IGMoMCwxKSkKIyAKIyBiZWVzd2FybShDZWxsLkFyZWEgfiBzaVJOQS4uT2xpZ28sIGRhdGEgPSBUYWxpbi5LRC5EYXRhLCBtZXRob2QgPSAnY2VudGVyJywgY29sID0gImJsYWNrIiwgcGNoID0gMTksIGNleCA9IDEsIHlsaW0gPSBjKDAsMSkpCiMgCiMgYmVlc3dhcm0oTWVhbi5DbHVzdGVyZWQuYjUucGVyLkNlbGwgfiBzaVJOQS4uT2xpZ28sIGRhdGEgPSBUYWxpbi5LRC5EYXRhLCBtZXRob2QgPSAnY2VudGVyJywgY29sID0gImJsYWNrIiwgcGNoID0gMTksIGNleCA9IDEpIywgeWxpbSA9IGMoMCwxKSkKCnBsb3QobG9nMihUYWxpbi5LRC5EYXRhJFRvdGFsLlRhbGluLnBlci5DZWxsKSwgVGFsaW4uS0QuRGF0YSRDZWxsLkFyZWEsIHlsaW0gPSBjKDAsMSksIHBjaCA9IGMoMCwgMCwgMCwgMCwgMiwgMjEpLCBjb2wgPSBjKCIxIiwgIjEiLCAiMSIsICIxIiwgIjIiLCAiMyIpKQphYmxpbmUobG0oVGFsaW4uS0QuRGF0YSRDZWxsLkFyZWEgfiBsb2cyKFRhbGluLktELkRhdGEkVG90YWwuVGFsaW4ucGVyLkNlbGwpKSwgY29sID0gImdyZXkiKQoKbG0uY2VsbC5hcmVhX3ZzX3RhbGluLnBlci5jZWxsIDwtIGxtKFRhbGluLktELkRhdGEkQ2VsbC5BcmVhIH4gbG9nMihUYWxpbi5LRC5EYXRhJFRvdGFsLlRhbGluLnBlci5DZWxsKSkKClRhbGluS0RfQ2VsbF9BcmVhX3BhbmVsX2ZpbGVfbmFtZSA8LSAiUGFuZWwgM0ggVGFsaW5LRF92c19DZWxsX0FyZWEiCgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBUYWxpbktEX0NlbGxfQXJlYV9wYW5lbF9maWxlX25hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD0zLCBoZWlnaHQ9MykKcGxvdChsb2cyKFRhbGluLktELkRhdGEkVG90YWwuVGFsaW4ucGVyLkNlbGwpLCBUYWxpbi5LRC5EYXRhJENlbGwuQXJlYSwgeWxpbSA9IGMoMCwxKSwgcGNoID0gYygwLCAwLCAwLCAwLCAyLCAyMSksIGNvbCA9IGMoIjEiLCAiMSIsICIxIiwgIjEiLCAiMiIsICIzIiksIGNleC5heGlzID0gMC41LCBjZXgubGFiZWwgPSAwLjUpCmFibGluZShsbShUYWxpbi5LRC5EYXRhJENlbGwuQXJlYSB+IGxvZzIoVGFsaW4uS0QuRGF0YSRUb3RhbC5UYWxpbi5wZXIuQ2VsbCkpLCBjb2wgPSAiZ3JleSIpCmRldi5vZmYoKQoKCnBsb3QoVGFsaW4uS0QuRGF0YSRUb3RhbC5UYWxpbi5wZXIuQ2VsbCwgbG9nMihUYWxpbi5LRC5EYXRhJE1lYW4uQ2x1c3RlcmVkLmI1LnBlci5DZWxsKSwgeGxpbSA9IGMoMCwxKSwgeWxpbSA9IGMoMCw0KSwgcGNoID0gYygwLCAwLCAwLCAwLCAyLCAyMSksICBjb2wgPSBjKCIxIiwgIjEiLCAiMSIsICIxIiwgIjIiLCAiMyIpKQphYmxpbmUobG0obG9nMihUYWxpbi5LRC5EYXRhJE1lYW4uQ2x1c3RlcmVkLmI1LnBlci5DZWxsKSB+IFRhbGluLktELkRhdGEkVG90YWwuVGFsaW4ucGVyLkNlbGwpLCBjb2wgPSAiZ3JleSIpCgpsbS5iNS5pbnRlbnNpdHlfdnNfdGFsaW4ucGVyLmNlbGwgPC0gbG0obG9nMihUYWxpbi5LRC5EYXRhJE1lYW4uQ2x1c3RlcmVkLmI1LnBlci5DZWxsKSB+IFRhbGluLktELkRhdGEkVG90YWwuVGFsaW4ucGVyLkNlbGwpCgpUYWxpbktEX2I1X0ludGVuc2l0eV9wYW5lbF9maWxlX25hbWUgPC0gIlBhbmVsIDNJIFRhbGluS0RfdnNfYjVfSW50ZW5zaXR5IgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBUYWxpbktEX2I1X0ludGVuc2l0eV9wYW5lbF9maWxlX25hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD0zLCBoZWlnaHQ9MykKcGxvdChUYWxpbi5LRC5EYXRhJFRvdGFsLlRhbGluLnBlci5DZWxsLCBsb2cyKFRhbGluLktELkRhdGEkTWVhbi5DbHVzdGVyZWQuYjUucGVyLkNlbGwpLCB4bGltID0gYygwLDEpLCB5bGltID0gYygwLDQpLCBwY2ggPSBjKDAsIDAsIDAsIDAsIDIsIDIxKSwgIGNvbCA9IGMoIjEiLCAiMSIsICIxIiwgIjEiLCAiMiIsICIzIiksIGNleC5heGlzID0gMC41LCBjZXgubGFiZWwgPSAwLjUpCmFibGluZShsbShsb2cyKFRhbGluLktELkRhdGEkTWVhbi5DbHVzdGVyZWQuYjUucGVyLkNlbGwpIH4gVGFsaW4uS0QuRGF0YSRUb3RhbC5UYWxpbi5wZXIuQ2VsbCksIGNvbCA9ICJncmV5IikKCmRldi5vZmYoKQpgYGAKCiMjIFRlc3QgQ3l0b0QgZWZmZWN0cyBvbiBhZGhlc2lvbiBpbnRlbnNpdGllcwojIyMjIFdpbGNveG9uIHJhbmsgc3VtIHRlc3Qgb2YgQ3l0b0QgZWZmZWN0IG9uIHZpbmN1bGluIGFuZCBiNSBpbnRlbnNpdHkgaW4gYWRoZXNpb25zCmBgYHtyIFdpbGNveG9uIHJhbmsgc3VtIHRlc3Qgb2YgQ3l0b0QgZWZmZWN0IG9uIHZpbmN1bGluIGFuZCBiNSBpbnRlbnNpdHkgaW4gYWRoZXNpb25zfQpuYW1lcyhDeXRvRDJoX3ZzX2NvbnRyb2wpIDwtIGMoIlZpbmN1bGluX0ludGVuc2l0eSIsICJiNV9JbnRlbnNpdHkiLCAiQ29uZGl0aW9uIikKClZpbmN1bGluX0ludGVuc2l0eV9tdV90ZXN0IDwtIHdpbGNveC50ZXN0KFZpbmN1bGluX0ludGVuc2l0eSB+IENvbmRpdGlvbiwgZGF0YSA9IEN5dG9EMmhfdnNfY29udHJvbCkkcC52YWx1ZQpwcmludChWaW5jdWxpbl9JbnRlbnNpdHlfbXVfdGVzdCkKCmI1X0ludGVuc2l0eV9tdV90ZXN0IDwtIHdpbGNveC50ZXN0KGI1X0ludGVuc2l0eSB+IENvbmRpdGlvbiwgZGF0YSA9IEN5dG9EMmhfdnNfY29udHJvbCkkcC52YWx1ZQpwcmludChiNV9JbnRlbnNpdHlfbXVfdGVzdCkKYGBgCgojIEZpZ3VyZSA1CgojIyBJbXBvcnQgRGF0YSBmb3IgRmlndXJlIDUKYGBge3IgSW1wb3J0IERhdGEgZm9yIEZpZ3VyZSA1fQojIFNldCB5b3VyIHBhdGggdG8gaW5wdXQgZGF0YQpkYXRhX2lucHV0X3BhdGggPC0gIi9Vc2Vycy9qb2hubG9jay9Ecm9wYm94L0EtQ01BQyBNYW5jaGVzdGVyIGNvbGxhYm9yYXRpb24vTkNCIHN1Ym1pc3Npb24gZG9jdW1lbnRzL1Jlc3VibWlzc2lvbiAyL1NvdXJjZV9EYXRhIgpkYXRhX2ZpbGUgPC0gIlN1cHBsZW1lbnRhcnkgVGFibGUgMSBTdGF0aXN0aWNzIFNvdXJjZSBEYXRhLnhsc3giCgojIEltcG9ydCBpbmRpdmlkdWFsIGRhdGEgZmlsZXMKUHJpbWFyeS5zaVJOQS5TY3JlZW4uRGF0YSA8LSAgcmVhZF94bHN4KHBhc3RlKGRhdGFfaW5wdXRfcGF0aCwgZGF0YV9maWxlLCBzZXAgPSAiLyIpLCBzaGVldCA9ICJGaWc1Ql9DIiwgY29sX25hbWVzID0gVFJVRSkKCk5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhIDwtIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiRmlnNUQiLCBjb2xfbmFtZXMgPSBUUlVFKQoKYGBgCgojIyBBbmFseXNlIFByaW1hcnkgc2lSTkEgU2NyZWVuIHJlc3BvbnNlcwojIyMgQm94cGxvdCBjaGFuZ2VzIGluIHJldGljdWxhciB0byBmb2NhbCBhZGhlc2lvbiBiNSBpbnRlbnNpdHkgcmF0aW8gZHVlIHRvIHNpUk5BCmBgYHtyIEJveHBsb3QgY2hhbmdlcyBpbiByZXRpY3VsYXIgdG8gZm9jYWwgYWRoZXNpb24gYjUgaW50ZW5zaXR5IHJhdGlvIGR1ZSB0byBzaVJOQX0Kc2lSTkFfYm94cGxvdF9zdW1tYXJ5X2ZpbGVuYW1lIDwtICJQYW5lbCA1QiBzaVJOQSBib3hwbG90IHN1bW1hcnkiCgpjZWxsLm51bWJlcnMucHJpbWFyeS5zY3JlZW4gPC0gY291bnQoUHJpbWFyeS5zaVJOQS5TY3JlZW4uRGF0YSwgc2lSTkFfVGFyZ2V0KQpjb3VudChQcmltYXJ5LnNpUk5BLlNjcmVlbi5EYXRhLCBzaVJOQV9UYXJnZXQpCm1lYW4uY2VsbC5udW1iZXJzLnByaW1hcnkuc2NyZWVuIDwtIHN1bW1hcmlzZShjZWxsLm51bWJlcnMucHJpbWFyeS5zY3JlZW4sIGF2ZyA9IG1lYW4obiksIFNEID0gc2QobiksIHN1bShuKSkKc3VtbWFyaXNlKGNlbGwubnVtYmVycy5wcmltYXJ5LnNjcmVlbiwgYXZnID0gbWVhbihuKSwgU0QgPSBzZChuKSwgc3VtKG4pKQoKZ2dwbG90KFByaW1hcnkuc2lSTkEuU2NyZWVuLkRhdGEsIGFlcyh4PXNpUk5BX1RhcmdldCwgeT1SYXRpb19BLkNNQUMudG8uVC5DTUFDX21lYW5faW50ZW5zaXR5Lnouc2NvcmUsIGNvbG9yID0gZmFjdG9yKHNpUk5BX1RyZWF0bWVudF9UeXBlKSkpICsgCiAgZ2VvbV9ib3hwbG90KG5vdGNoID0gVFJVRSwgb3V0bGllci5jb2xvdXIgPSAiTkEiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlVudHJlYXRlZCIsIk1PQ0siLCJTU1RfM0N0cmxfUG9vbCIsICJPTi1UQVJHRVRwbHVzIE5vbi10YXJnZXRpbmcgQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNpR0VOT01FIE5vbi10YXJnZXRpbmcgQ29udHJvbCIsICJJVEdBViIsICJJVEdCNSIsICJPQ1JMIiwgIlBJNEtBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEk0SzJCIiwgIlBURU4iLCAiUElQNUsxQiIsICJQSVA1SzFDIiwgIlBJSzNDMkEiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCkpICsKICB5bGltKC0zLCA2KSMrCgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBzaVJOQV9ib3hwbG90X3N1bW1hcnlfZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD03LCBoZWlnaHQ9NSkKCmdncGxvdChQcmltYXJ5LnNpUk5BLlNjcmVlbi5EYXRhLCBhZXMoeD1zaVJOQV9UYXJnZXQsIHk9UmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlLCBjb2xvciA9IGZhY3RvcihzaVJOQV9UcmVhdG1lbnRfVHlwZSkpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJVbnRyZWF0ZWQiLCJNT0NLIiwiU1NUXzNDdHJsX1Bvb2wiLCAiT04tVEFSR0VUcGx1cyBOb24tdGFyZ2V0aW5nIENvbnRyb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzaUdFTk9NRSBOb24tdGFyZ2V0aW5nIENvbnRyb2wiLCAiSVRHQVYiLCAiSVRHQjUiLCAiT0NSTCIsICJQSTRLQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBJNEsyQiIsICJQVEVOIiwgIlBJUDVLMUIiLCAiUElQNUsxQyIsICJQSUszQzJBIikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9OTApKSArCiAgeWxpbSgtMywgNikjKwoKZGV2Lm9mZigpCgpgYGAKCiMjIyBQYXJhbGxlbCBjb29yZGluYXRlcyBwbG90IG9mIGFkaGVzaW9uIHJlc3BvbnNlcyB0byBzaVJOQQpgYGB7ciBQYXJhbGxlbCBjb29yZGluYXRlcyBwbG90IG9mIGFkaGVzaW9uIHJlc3BvbnNlcyB0byBzaVJOQX0Kc2lSTkFfcGFyY29vcmRfc3VtbWFyeV9maWxlbmFtZSA8LSAiUGFuZWwgNUMgc2lSTkEgcGFyY29vcmQgc3VtbWFyeSIKClByaW1hcnlfc2NyZWVuX3NpUk5BX3N1YnNldCA8LSBzdWJzZXQoUHJpbWFyeS5zaVJOQS5TY3JlZW4uRGF0YSwgc2lSTkFfVGFyZ2V0ID09ICJVbnRyZWF0ZWQiIHwgc2lSTkFfVGFyZ2V0ID09ICJNT0NLIiB8IHNpUk5BX1RhcmdldCA9PSAiU1NUXzNDdHJsX1Bvb2wiIHwgc2lSTkFfVGFyZ2V0ID09ICAiT04tVEFSR0VUcGx1cyBOb24tdGFyZ2V0aW5nIENvbnRyb2wiIHwgc2lSTkFfVGFyZ2V0ID09ICJzaUdFTk9NRSBOb24tdGFyZ2V0aW5nIENvbnRyb2wiIHwgc2lSTkFfVGFyZ2V0ID09ICAiT0NSTCIgfCBzaVJOQV9UYXJnZXQgPT0gICJQSTRLQSIgfCBzaVJOQV9UYXJnZXQgPT0gIlBJNEsyQiIgfCBzaVJOQV9UYXJnZXQgPT0gICJQVEVOIiB8IHNpUk5BX1RhcmdldCA9PSAgIlBJUDVLMUIiIHwgc2lSTkFfVGFyZ2V0ID09ICAiUElQNUsxQyIgfCBzaVJOQV9UYXJnZXQgPT0gICJQSUszQzJBIikKClByaW1hcnlfc2NyZWVuX3NpUk5BX3N1YnNldF9ncm91cGVkIDwtIGFnZ3JlZ2F0ZShQcmltYXJ5X3NjcmVlbl9zaVJOQV9zdWJzZXRbLCBjKDExLDEzLDE4KV0sIGxpc3QoUHJpbWFyeV9zY3JlZW5fc2lSTkFfc3Vic2V0JHNpUk5BX1RhcmdldCksIG1lZGlhbikKClByaW1hcnlfc2NyZWVuX3NpUk5BX3N1YnNldF9ncm91cGVkJEdyb3VwLjEgPC0gCiAgYXMuZmFjdG9yKFByaW1hcnlfc2NyZWVuX3NpUk5BX3N1YnNldF9ncm91cGVkJEdyb3VwLjEpCgpuYW1lcyhQcmltYXJ5X3NjcmVlbl9zaVJOQV9zdWJzZXRfZ3JvdXBlZCkgPC0gYygic2lSTkFfVGFyZ2V0IiwgIk1lYW5fUmV0aWN1bGFyX0FkaGVzaW9uX0ludGVuc2l0eSIsICJNZWFuX0ZvY2FsX0FkaGVzaW9uX0ludGVuc2l0eSIsICJSYXRpb19SZXRpY3VsYXJfRm9jYWxfQWRoZXNpb25fSW50ZW5zaXR5IikKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIHNpUk5BX3BhcmNvb3JkX3N1bW1hcnlfZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD03LCBoZWlnaHQ9NSkKCmdncGFyY29vcmQoUHJpbWFyeV9zY3JlZW5fc2lSTkFfc3Vic2V0X2dyb3VwZWQsIGNvbHVtbnMgPSBjKDIsMyw0KSwgZ3JvdXBDb2x1bW4gPSAxLCBzY2FsZSA9ICJnbG9iYWxtaW5tYXgiLCBvcmRlciA9IGMoMiwzLDQpKSArIHRoZW1lKGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3QgPSAxLCBzaXplID0gNSkpCgpkZXYub2ZmKCkKCmdncGFyY29vcmQoUHJpbWFyeV9zY3JlZW5fc2lSTkFfc3Vic2V0X2dyb3VwZWQsIGNvbHVtbnMgPSBjKDIsMyw0KSwgZ3JvdXBDb2x1bW4gPSAxLCBzY2FsZSA9ICJnbG9iYWxtaW5tYXgiLCBvcmRlciA9IGMoMiwzLDQpKSArIHRoZW1lKGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3QgPSAxLCBzaXplID0gNSkpCgpgYGAKCgojIyMgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IHNpUk5BIHRyZWF0bWVudCBlZmZlY3RzCmBgYHtyIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBzaVJOQSB0cmVhdG1lbnQgZWZmZWN0c30Kc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0IDwtIHN1YnNldChQcmltYXJ5LnNpUk5BLlNjcmVlbi5EYXRhLCBzaVJOQV9UYXJnZXQgIT0gIlVudHJlYXRlZCIgJiBzaVJOQV9UYXJnZXQgIT0gIk1PQ0siICYgc2lSTkFfVGFyZ2V0ICE9ICJTU1RfM0N0cmxfUG9vbCIgJiBzaVJOQV9UYXJnZXQgIT0gInNpR0VOT01FIE5vbi10YXJnZXRpbmcgQ29udHJvbCIpIAoKcF92YWx1ZXMgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKXsKICBmb3IgKGogaW4gMTpsZW5ndGgodW5pcXVlKHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQpKSl7CiAgICBzaVJOQV9UYXJnZXRfMSA9IHN1YnNldChzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3QsIHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQgPT0gdW5pcXVlKHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQpW2ldKQogICAgc2lSTkFfVGFyZ2V0XzEkc2lSTkFfVGFyZ2V0X051bWJlciA9IGFzLmZhY3RvcihpKQogICAgc2lSTkFfVGFyZ2V0XzIgPSBzdWJzZXQoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0LCBzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0ID09IHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KVtqXSkKICAgIHNpUk5BX1RhcmdldF8yJHNpUk5BX1RhcmdldF9OdW1iZXIgPSBhcy5mYWN0b3IoaisxMDApCiAgICBzaVJOQV9UYXJnZXRfUGFpciA9IHJiaW5kKHNpUk5BX1RhcmdldF8xLCBzaVJOQV9UYXJnZXRfMikKICAgIHNpUk5BX1RhcmdldF9QYWlyX3R0ZXN0ID0gd2lsY294LnRlc3QoUmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlIH4gc2lSTkFfVGFyZ2V0X051bWJlciwgZGF0YSA9IHNpUk5BX1RhcmdldF9QYWlyKSRwLnZhbHVlCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBzaVJOQV9UYXJnZXRfUGFpcl90dGVzdCkKICB9Cn0KCnBfdmFsdWVzIDwtIGFzLnZlY3RvcihwX3ZhbHVlcykKCnBfdmFsdWVfbWF0cml4IDwtIG1hdHJpeChwX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSkKcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShwX3ZhbHVlX21hdHJpeCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMocF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCiMgcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgojIEludHJvZHVjZSBIb2xtIChhbHNvIGNhbGxlZCBIb2xtLUJvbmZlcnJvbmkpIHAtdmFsdWUgY29ycmVjdGlvbiAodXNlZCBiZWNhdXNlIGl0IGdpdmVzIHNhbWUgc3RyaW5nZW5jeSBhZ2FpbnN0IGZhbHNlIHBvc2l0aXZlcyAodHlwZSAxIGVycm9ycykgd2l0aCBsb3dlciBwcm9iYWJpbGl0eSBvZiBmYWxzZSBuZWdhdGl2ZXMgKHR5cGUgMiBlcnJvcnMpKSkKCmNvcnJlY3RlZF9wX3ZhbHVlcyA8LSBwLmFkanVzdChwX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iLCBuID0gbGVuZ3RoKHBfdmFsdWVzKSkKCmNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDIgPC0gbWF0cml4KGNvcnJlY3RlZF9wX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSkKY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUoY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4Miwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgpwcmludChjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpCgpgYGAKCiMjIyBQbG90IGhlYXRtYXAgb2YgY29ycmVjdGVkIHBfdmFsdWVzIG1hbm4td2hpdG5leQpgYGB7ciBQbG90IGhlYXRtYXAgb2YgY29ycmVjdGVkIHBfdmFsdWVzIG1hbm4td2hpdG5leSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0KaGVhdG1hcC4yKGxvZyhjb3JyZWN0ZWRfcF92YWx1ZV9tYXRyaXgyKSwgZGVuZHJvZ3JhbSA9ICdub25lJywgUm93diA9IEZBTFNFLCBDb2x2ID0gRkFMU0UsIGxhYlJvdyA9IHJvd3MsIGxhYkNvbCA9IGNvbHVtbnMsIHNydENvbCA9IDQ1LCBjZXhSb3cgPSAxLCBjZXhDb2wgPSAxLCBtYXJnaW5zID0gYyg3LCA5KSwgc3ltbSA9IFRSVUUsIHJldkMgPSBGQUxTRSwgYnJlYWtzID0gYyhsb2coMWUtMzAwKSwgbG9nKDFlLTUwKSwgbG9nKDFlLTEwKSwgbG9nKDFlLTYpLCBsb2coMC4wMDEpLCBsb2coMC4wMSksIGxvZygwLjA1KSwgbG9nKDEpKSwgcm93c2VwID0gMTpucm93KGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDIpLCBjb2xzZXAgPSAxOm5jb2woY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4MiksIHNlcGNvbG9yID0gJ2RhcmtncmV5Jywgc2Vwd2lkdGggPSBjKDAuMDIsMC4wMiksIHRyYWNlID0gJ25vbmUnLCBjb2wgPSBjKCJkYXJrcmVkIiwgInJlZCIsICJvcmFuZ2UiLCAiZ3JlZW4iLCAiYmx1ZSIsICJwdXJwbGUiLCAibGlnaHRncmV5IiksIGRlbnNjb2wgPSBOVUxMLCBrZXlzaXplID0gMS41LCBrZXkudGl0bGUgPSBOQSkKYGBgCgojIyBBbmFseXNlIE5lb215Y2luIGFuZCBMWSBkcnVnIHRyZWF0bWVudCByZXNwb25zZXMKCiMjIyBCb3hwbG90cyBvZiBiNSBhZGhlc2lvbiBpbnRlbnNpdHkgY2hhbmdlcyBkdWUgdG8gbmVvbXljaW4gb3IgTFkKYGBge3IgQm94cGxvdHMgb2YgYjUgYWRoZXNpb24gaW50ZW5zaXR5IGNoYW5nZXMgZHVlIHRvIG5lb215Y2luIG9yIExZfQpQSVBfZHJ1Z19ib3hwbG90X3N1bW1hcnlfZmlsZW5hbWUgPC0gIlBhbmVsIDVEIFBJUCBkcnVnIGJveHBsb3Qgc3VtbWFyeSIKCmNlbGwubnVtYmVycy5ORU9fTFkuc2NyZWVuIDwtIGNvdW50KE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhLCBEcnVnKQpjb3VudChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgRHJ1ZykKbWVhbi5jZWxsLm51bWJlcnMuTkVPX0xZLnNjcmVlbiA8LSBzdW1tYXJpc2UoY2VsbC5udW1iZXJzLk5FT19MWS5zY3JlZW4sIGF2ZyA9IG1lYW4obiksIFNEID0gc2QobiksIHN1bShuKSkKc3VtbWFyaXNlKGNlbGwubnVtYmVycy5ORU9fTFkuc2NyZWVuLCBhdmcgPSBtZWFuKG4pLCBTRCA9IHNkKG4pLCBzdW0obikpCgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBQSVBfZHJ1Z19ib3hwbG90X3N1bW1hcnlfZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD03LCBoZWlnaHQ9NSkKCnAxIDwtIGdncGxvdChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgYWVzKHg9RHJ1ZywgeT1NZWRpYW4uTWVhbi4uei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJETVNPIiwgIk5lb18xMG1NIiwiTFlfMjVtTSIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCB2anVzdCA9IDAuNSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKC0zLCA2KSkgKyB5bGFiKCJNZWFuIFJldGljdWxhciBBZGhlc2lvbiBJbnRlbnNpdHkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKIyMgcGxvdCBULUNNQUMgaW50ZW5zaXR5IFotc2NvcmUgZ2dwbG90MiBib3hwbG90IC0gcGVyIERydWcgCgpwMiA8LSBnZ3Bsb3QoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEsIGFlcyh4PURydWcsIHk9TWVkaWFuLk1lYW4uX1QuQ01BQ3Muei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJETVNPIiwgIk5lb18xMG1NIiwiTFlfMjVtTSIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCB2anVzdCA9IDAuNSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKC0zLCA2KSkgKyB5bGFiKCJNZWFuIEZvY2FsIEFkaGVzaW9uIEludGVuc2l0eSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCiMjIHBsb3QgaW50ZW5zaXR5IHJhdGlvIFotc2NvcmUgZ2dwbG90MiBib3hwbG90IC0gcGVyIERydWcgCgpwMyA8LSBnZ3Bsb3QoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEsIGFlcyh4PURydWcsIHk9UmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlLCBjb2xvciA9IGZhY3RvcihEcnVnKSkpICsgCiAgZ2VvbV9ib3hwbG90KG5vdGNoID0gVFJVRSwgb3V0bGllci5jb2xvdXIgPSAiTkEiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIkRNU08iLCAiTmVvXzEwbU0iLCJMWV8yNW1NIikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIHZqdXN0ID0gMC41KSkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoLTMsIDYpKSArIHlsYWIoIlJhdGlvIFJldGljdWxhcjpGb2NhbCBBZGhlc2lvbiBJbnRlbnNpdHkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgbmNvbCA9IDMpCgpkZXYub2ZmKCkKCnAxIDwtIGdncGxvdChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgYWVzKHg9RHJ1ZywgeT1NZWRpYW4uTWVhbi4uei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJETVNPIiwgIk5lb18xMG1NIiwiTFlfMjVtTSIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCB2anVzdCA9IDAuNSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKC0zLCA2KSkgKyB5bGFiKCJNZWFuIFJldGljdWxhciBBZGhlc2lvbiBJbnRlbnNpdHkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKIyMgcGxvdCBULUNNQUMgaW50ZW5zaXR5IFotc2NvcmUgZ2dwbG90MiBib3hwbG90IC0gcGVyIERydWcgCgpwMiA8LSBnZ3Bsb3QoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEsIGFlcyh4PURydWcsIHk9TWVkaWFuLk1lYW4uX1QuQ01BQ3Muei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJETVNPIiwgIk5lb18xMG1NIiwiTFlfMjVtTSIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCB2anVzdCA9IDAuNSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKC0zLCA2KSkgKyB5bGFiKCJNZWFuIEZvY2FsIEFkaGVzaW9uIEludGVuc2l0eSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCiMjIHBsb3QgaW50ZW5zaXR5IHJhdGlvIFotc2NvcmUgZ2dwbG90MiBib3hwbG90IC0gcGVyIERydWcgCgpwMyA8LSBnZ3Bsb3QoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEsIGFlcyh4PURydWcsIHk9UmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlLCBjb2xvciA9IGZhY3RvcihEcnVnKSkpICsgCiAgZ2VvbV9ib3hwbG90KG5vdGNoID0gVFJVRSwgb3V0bGllci5jb2xvdXIgPSAiTkEiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIkRNU08iLCAiTmVvXzEwbU0iLCJMWV8yNW1NIikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIHZqdXN0ID0gMC41KSkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoLTMsIDYpKSArIHlsYWIoIlJhdGlvIFJldGljdWxhcjpGb2NhbCBBZGhlc2lvbiBJbnRlbnNpdHkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgbmNvbCA9IDMpCgoKYGBgCgojIyMgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IERydWcgdHJlYXRtZW50IGVmZmVjdHMgb24gUmV0aWN1bGFyIGFkaGVzaW9uIGludGVuc2l0eQpgYGB7ciBNYW5uLVdoaXRuZXkgdGVzdCBmb3Igc2lnbmlmaWNhbnQgRHJ1ZyB0cmVhdG1lbnQgZWZmZWN0cyBvbiBSZXRpY3VsYXIgYWRoZXNpb24gaW50ZW5zaXR5fQpwX3ZhbHVlcyA8LSBjKCkKZm9yIChpIGluIDE6bGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkpewogIGZvciAoaiBpbiAxOmxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpKXsKICAgIERydWdfMSA9IHN1YnNldChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZyA9PSB1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZylbaV0pCiAgICBEcnVnXzEkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaSkKICAgIERydWdfMiA9IHN1YnNldChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZyA9PSB1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1Zylbal0pCiAgICBEcnVnXzIkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaisxMDApCiAgICBEcnVnX1BhaXIgPSByYmluZChEcnVnXzEsIERydWdfMikKICAgIERydWdfUGFpcl90dGVzdCA9IHdpbGNveC50ZXN0KE1lZGlhbi5NZWFuLi56LnNjb3JlIH4gRHJ1Z19OdW1iZXIsIGRhdGEgPSBEcnVnX1BhaXIpJHAudmFsdWUKICAgIHBfdmFsdWVzID0gcmJpbmQocF92YWx1ZXMsIERydWdfUGFpcl90dGVzdCkKICB9Cn0KCnBfdmFsdWVzIDwtIGFzLnZlY3RvcihwX3ZhbHVlcykKCnBfdmFsdWVfbWF0cml4IDwtIG1hdHJpeChwX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkKcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShwX3ZhbHVlX21hdHJpeCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMocF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCiMgcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgojIEludHJvZHVjZSBIb2xtIChhbHNvIGNhbGxlZCBIb2xtLUJvbmZlcnJvbmkpIHAtdmFsdWUgY29ycmVjdGlvbiAodXNlZCBiZWNhdXNlIGl0IGdpdmVzIHNhbWUgc3RyaW5nZW5jeSBhZ2FpbnN0IGZhbHNlIHBvc2l0aXZlcyAodHlwZSAxIGVycm9ycykgd2l0aCBsb3dlciBwcm9iYWJpbGl0eSBvZiBmYWxzZSBuZWdhdGl2ZXMgKHR5cGUgMiBlcnJvcnMpKSkKCmNvcnJlY3RlZF9wX3ZhbHVlcyA8LSBwLmFkanVzdChwX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iLCBuID0gbGVuZ3RoKHBfdmFsdWVzKSkKCmNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDMgPC0gbWF0cml4KGNvcnJlY3RlZF9wX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkKY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUoY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4Mywgcm93Lm5hbWVzID0gcm93cykKbmFtZXMoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgpwcmludChjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpCmBgYAoKIyMjIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBEcnVnIHRyZWF0bWVudCBlZmZlY3RzIG9uIEZvY2FsIGFkaGVzaW9uIGludGVuc2l0eQpgYGB7ciBNYW5uLVdoaXRuZXkgdGVzdCBmb3Igc2lnbmlmaWNhbnQgRHJ1ZyB0cmVhdG1lbnQgZWZmZWN0cyBvbiBGb2NhbCBhZGhlc2lvbiBpbnRlbnNpdHl9CnBfdmFsdWVzIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKSl7CiAgZm9yIChqIGluIDE6bGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkpewogICAgRHJ1Z18xID0gc3Vic2V0KE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhLCBOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnID09IHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKVtpXSkKICAgIERydWdfMSREcnVnX051bWJlciA9IGFzLmZhY3RvcihpKQogICAgRHJ1Z18yID0gc3Vic2V0KE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhLCBOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnID09IHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKVtqXSkKICAgIERydWdfMiREcnVnX051bWJlciA9IGFzLmZhY3RvcihqKzEwMCkKICAgIERydWdfUGFpciA9IHJiaW5kKERydWdfMSwgRHJ1Z18yKQogICAgRHJ1Z19QYWlyX3R0ZXN0ID0gd2lsY294LnRlc3QoTWVkaWFuLk1lYW4uX1QuQ01BQ3Muei5zY29yZSB+IERydWdfTnVtYmVyLCBkYXRhID0gRHJ1Z19QYWlyKSRwLnZhbHVlCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBEcnVnX1BhaXJfdHRlc3QpCiAgfQp9CgpwX3ZhbHVlcyA8LSBhcy52ZWN0b3IocF92YWx1ZXMpCgpwX3ZhbHVlX21hdHJpeCA8LSBtYXRyaXgocF92YWx1ZXMsbnJvdyA9IGxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpLG5jb2wgPSBsZW5ndGgodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKQpyb3dzIDwtIGFzLnZlY3Rvcih1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpCnBfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUocF92YWx1ZV9tYXRyaXgsIHJvdy5uYW1lcyA9IHJvd3MpCm5hbWVzKHBfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgojIHByaW50KHBfdmFsdWVfZGF0YWZyYW1lKQoKIyBJbnRyb2R1Y2UgSG9sbSAoYWxzbyBjYWxsZWQgSG9sbS1Cb25mZXJyb25pKSBwLXZhbHVlIGNvcnJlY3Rpb24gKHVzZWQgYmVjYXVzZSBpdCBnaXZlcyBzYW1lIHN0cmluZ2VuY3kgYWdhaW5zdCBmYWxzZSBwb3NpdGl2ZXMgKHR5cGUgMSBlcnJvcnMpIHdpdGggbG93ZXIgcHJvYmFiaWxpdHkgb2YgZmFsc2UgbmVnYXRpdmVzICh0eXBlIDIgZXJyb3JzKSkpCgpjb3JyZWN0ZWRfcF92YWx1ZXMgPC0gcC5hZGp1c3QocF92YWx1ZXMsIG1ldGhvZCA9ICJob2xtIiwgbiA9IGxlbmd0aChwX3ZhbHVlcykpCgpjb3JyZWN0ZWRfcF92YWx1ZV9tYXRyaXg0IDwtIG1hdHJpeChjb3JyZWN0ZWRfcF92YWx1ZXMsbnJvdyA9IGxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpLG5jb2wgPSBsZW5ndGgodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKQpyb3dzIDwtIGFzLnZlY3Rvcih1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpCmNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDQsIHJvdy5uYW1lcyA9IHJvd3MpCm5hbWVzKGNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKcHJpbnQoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKQpgYGAKIyMjIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBEcnVnIHRyZWF0bWVudCBlZmZlY3RzIG9uIGludGVuc2l0eSByYXRpbyBaLXNjb3JlCmBgYHtyIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBEcnVnIHRyZWF0bWVudCBlZmZlY3RzIG9uIGludGVuc2l0eSByYXRpbyBaLXNjb3JlfQpwX3ZhbHVlcyA8LSBjKCkKZm9yIChpIGluIDE6bGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkpewogIGZvciAoaiBpbiAxOmxlbmd0aCh1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZykpKXsKICAgIERydWdfMSA9IHN1YnNldChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZyA9PSB1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZylbaV0pCiAgICBEcnVnXzEkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaSkKICAgIERydWdfMiA9IHN1YnNldChOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSwgTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1ZyA9PSB1bmlxdWUoTmVvLkxZLkRydWcuVHJlYXRtZW50LkRhdGEkRHJ1Zylbal0pCiAgICBEcnVnXzIkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaisxMDApCiAgICBEcnVnX1BhaXIgPSByYmluZChEcnVnXzEsIERydWdfMikKICAgIERydWdfUGFpcl90dGVzdCA9IHdpbGNveC50ZXN0KGFzLm51bWVyaWMoUmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlKSB+IERydWdfTnVtYmVyLCBkYXRhID0gRHJ1Z19QYWlyKSRwLnZhbHVlIAogICAgcF92YWx1ZXMgPSByYmluZChwX3ZhbHVlcywgRHJ1Z19QYWlyX3R0ZXN0KQogIH0KfQoKcF92YWx1ZXMgPC0gYXMudmVjdG9yKHBfdmFsdWVzKQoKcF92YWx1ZV9tYXRyaXggPC0gbWF0cml4KHBfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKSxuY29sID0gbGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkpCmNvbHVtbnMgPC0gYXMudmVjdG9yKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKQpwX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKHBfdmFsdWVfbWF0cml4LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhwX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKIyBwcmludChwX3ZhbHVlX2RhdGFmcmFtZSkKCiMgSW50cm9kdWNlIEhvbG0gKGFsc28gY2FsbGVkIEhvbG0tQm9uZmVycm9uaSkgcC12YWx1ZSBjb3JyZWN0aW9uICh1c2VkIGJlY2F1c2UgaXQgZ2l2ZXMgc2FtZSBzdHJpbmdlbmN5IGFnYWluc3QgZmFsc2UgcG9zaXRpdmVzICh0eXBlIDEgZXJyb3JzKSB3aXRoIGxvd2VyIHByb2JhYmlsaXR5IG9mIGZhbHNlIG5lZ2F0aXZlcyAodHlwZSAyIGVycm9ycykpKQoKY29ycmVjdGVkX3BfdmFsdWVzIDwtIHAuYWRqdXN0KHBfdmFsdWVzLCBtZXRob2QgPSAiaG9sbSIsIG4gPSBsZW5ndGgocF92YWx1ZXMpKQoKY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4NSA8LSBtYXRyaXgoY29ycmVjdGVkX3BfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKSxuY29sID0gbGVuZ3RoKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkpCmNvbHVtbnMgPC0gYXMudmVjdG9yKHVuaXF1ZShOZW8uTFkuRHJ1Zy5UcmVhdG1lbnQuRGF0YSREcnVnKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKE5lby5MWS5EcnVnLlRyZWF0bWVudC5EYXRhJERydWcpKQpjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShjb3JyZWN0ZWRfcF92YWx1ZV9tYXRyaXg1LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCnByaW50KGNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSkKYGBgCiMgRmlndXJlIDYKCiMjIEltcG9ydCBEYXRhIGZvciBGaWd1cmUgNgpgYGB7ciBtcG9ydCBEYXRhIGZvciBGaWd1cmUgNn0KCiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCmRhdGFfaW5wdXRfcGF0aCA8LSAiL1VzZXJzL2pvaG5sb2NrL0Ryb3Bib3gvQS1DTUFDIE1hbmNoZXN0ZXIgY29sbGFib3JhdGlvbi9OQ0Igc3VibWlzc2lvbiBkb2N1bWVudHMvUmVzdWJtaXNzaW9uIDIvU291cmNlX0RhdGEiCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCiMgSW1wb3J0IGluZGl2aWR1YWwgZGF0YSBmaWxlcwoKUHJvbGlmZXJhdGlvbiA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzZBIiwgY29sX25hbWVzID0gVFJVRSkKUHJvbGlmZXJhdGlvbiREYXkgPC0gYXMuZmFjdG9yKFByb2xpZmVyYXRpb24kRGF5KQoKCkVEVV9JbmNvcnBvcmF0aW9uX1BlcmNlbnRhZ2UgPC0gIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiRmlnNkIiLCBjb2xfbmFtZXMgPSBUUlVFKQpFRFVfSW5jb3Jwb3JhdGlvbl9QZXJjZW50YWdlIDwtIEVEVV9JbmNvcnBvcmF0aW9uX1BlcmNlbnRhZ2VbLDE6Ml0KCmBgYAoKIyMgU3VtbWFyaXNlIFByb2xpZmVyYXRpb24gZGF0YSBwZXIgQ29uZGl0aW9uIHBlciBEYXkKYGBge3IgU3VtbWFyaXNlIFByb2xpZmVyYXRpb24gZGF0YSBwZXIgQ29uZGl0aW9uIHBlciBEYXl9ClByb2xfU3VtIDwtIFByb2xpZmVyYXRpb24gJT4lCiAgZ3JvdXBfYnkoLmRvdHMgPSBjKCdDb25kaXRpb24nLCAnRGF5JykpICU+JQogIHN1bW1hcmlzZSgKICAgIG1lYW5fcHJvbGlmZXJhdGlvbiA9IG1lYW4oUmVsYXRpdmUuUHJvbGlmZXJhdGlvbiwgbmEucm0gPSBUUlVFKSwKICAgIFNEX3Byb2xpZmVyYXRpb24gPSBzZChSZWxhdGl2ZS5Qcm9saWZlcmF0aW9uLCBuYS5ybSA9IFRSVUUpCiAgKQpgYGAKCiMjIyBQbG90IENlbGwgUHJvbGlmZXJhdGlvbiBDb21wYXJpc29uIG9mIGNvbnRyb2wgdnMgYjVLRApgYGB7ciBQbG90IENlbGwgUHJvbGlmZXJhdGlvbiBDb21wYXJpc29uIG9mIGNvbnRyb2wgdnMgYjVLRH0KcHJvbGlmZXJhdGlvbl9saW5lY2hhcnRfZmlsZW5hbWUgPC0gIlBhbmVsIDZBIHByb2xpZmVyYXRpb24gbGluZWNoYXJ0IgoKIyBUaGUgZXJyb3JiYXJzIG92ZXJsYXBwZWQsIHNvIHVzZSBwb3NpdGlvbl9kb2RnZSB0byBtb3ZlIHRoZW0gaG9yaXpvbnRhbGx5CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuMSkgIyBtb3ZlIHRoZW0gLjA1IHRvIHRoZSBsZWZ0IGFuZCByaWdodAoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgcHJvbGlmZXJhdGlvbl9saW5lY2hhcnRfZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD00LCBoZWlnaHQ9MykKCmdncGxvdChQcm9sX1N1bSwgYWVzKHg9RGF5LCB5PW1lYW5fcHJvbGlmZXJhdGlvbiwgY29sb3VyPUNvbmRpdGlvbiwgZ3JvdXA9Q29uZGl0aW9uKSkgKyAKICAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bWVhbl9wcm9saWZlcmF0aW9uLVNEX3Byb2xpZmVyYXRpb24sIHltYXg9bWVhbl9wcm9saWZlcmF0aW9uK1NEX3Byb2xpZmVyYXRpb24pLCB3aWR0aD0uMSwgcG9zaXRpb249cGQpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiQ29udHJvbCIgPSAiIzQ5NDk0QSIsICJiNUtEIiA9ICIjRUMxQzI0IikpICsKICAgIGdlb21fbGluZShwb3NpdGlvbj1wZCwgc2l6ZSA9IDEpICsKICAgIGdlb21fcG9pbnQocG9zaXRpb249cGQsIHNpemU9Mywgc2hhcGU9MTkpICsgIyAyMSBpcyBmaWxsZWQgY2lyY2xlCiAgICB4bGFiKCJEYXkiKSArCiAgICB5bGFiKCJSZWxhdGl2ZSBQcm9saWZlcmF0aW9uIikgKwogICAgdGhlbWVfbGlnaHQoKQoKZGV2Lm9mZigpCgpnZ3Bsb3QoUHJvbF9TdW0sIGFlcyh4PURheSwgeT1tZWFuX3Byb2xpZmVyYXRpb24sIGNvbG91cj1Db25kaXRpb24sIGdyb3VwPUNvbmRpdGlvbikpICsgCiAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW5fcHJvbGlmZXJhdGlvbi1TRF9wcm9saWZlcmF0aW9uLCB5bWF4PW1lYW5fcHJvbGlmZXJhdGlvbitTRF9wcm9saWZlcmF0aW9uKSwgd2lkdGg9LjEsIHBvc2l0aW9uPXBkKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIkNvbnRyb2wiID0gIiM0OTQ5NEEiLCAiYjVLRCIgPSAiI0VDMUMyNCIpKSArCiAgICBnZW9tX2xpbmUocG9zaXRpb249cGQsIHNpemUgPSAxKSArCiAgICBnZW9tX3BvaW50KHBvc2l0aW9uPXBkLCBzaXplPTMsIHNoYXBlPTE5KSArICMgMjEgaXMgZmlsbGVkIGNpcmNsZQogICAgeGxhYigiRGF5IikgKwogICAgeWxhYigiUmVsYXRpdmUgUHJvbGlmZXJhdGlvbiIpICsKICAgIHRoZW1lX2xpZ2h0KCkKCmBgYAoKIyMjIFQtdGVzdGluZyBDZWxsIFByb2xpZmVyYXRpb24gQ29tcGFyaXNvbiBwZXIgQ29uZGl0aW9uIHBlciBEYXkKYGBge3IgVC10ZXN0aW5nIENlbGwgUHJvbGlmZXJhdGlvbiBDb21wYXJpc29uIHBlciBDb25kaXRpb24gcGVyIERheX0KClByb2xpZmVyYXRpb24kRGF5IDwtIGFzLmZhY3RvcihQcm9saWZlcmF0aW9uJERheSkKCnBfdmFsdWVzIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgodW5pcXVlKFByb2xpZmVyYXRpb24kRGF5KSkpewogIAogICAgc2luZ2xlX2RheV9kYXRhID0gc3Vic2V0KFByb2xpZmVyYXRpb24sIFByb2xpZmVyYXRpb24kRGF5ID09IHVuaXF1ZShQcm9saWZlcmF0aW9uJERheSlbaV0pCiAgICAKICAgIENvbnRyb2xfdnNfYjVLRF9wZXJfZGF5X3R0ZXN0ID0gdC50ZXN0KFJlbGF0aXZlLlByb2xpZmVyYXRpb24gfiBDb25kaXRpb24sIGRhdGEgPSBzaW5nbGVfZGF5X2RhdGEsIHBhaXJlZCA9IEZBTFNFKSRwLnZhbHVlCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBDb250cm9sX3ZzX2I1S0RfcGVyX2RheV90dGVzdCkKCn0KCnBfdmFsdWVzIDwtIGFzLnZlY3RvcihwX3ZhbHVlcykKCnBfdmFsdWVfbWF0cml4IDwtIG1hdHJpeChwX3ZhbHVlcyxucm93ID0gMSxuY29sID0gbGVuZ3RoKHBfdmFsdWVzKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IocGFzdGUoIkRheSIsIHVuaXF1ZShQcm9saWZlcmF0aW9uJERheSksIHNlcCA9ICIgIikpCnJvd3MgPC0gcGFzdGUodW5pcXVlKFByb2xpZmVyYXRpb24kQ29uZGl0aW9uKVsxXSwgdW5pcXVlKFByb2xpZmVyYXRpb24kQ29uZGl0aW9uKVsyXSwgc2VwID0gIl92c18iKQpwX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKHBfdmFsdWVfbWF0cml4LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhwX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgpgYGAKCgojIyBFRFUgSW5jb3Jwb3JhdGlvbiBDb21wYXJpc29uIHBlciBDb25kaXRpb24KIyMjIEZpZyA2QiBQbG90IEVEVSBJbmNvcnBvcmF0aW9uIEJveHBsb3QgcGVyIENvbmRpdGlvbgpgYGB7ciBQbG90IEVEVSBJbmNvcnBvcmF0aW9uIEJveHBsb3QgcGVyIENvbmRpdGlvbn0KCiNkZWZpbmUgcGFuZWxfZmlsZV9uYW1lCkVEVV9ib3hwbG90X3BhbmVsX2ZpbGVfbmFtZSA8LSAiUGFuZWwgNkIgRURVIEluY29ycG9yYXRpb24gQm94cGxvdHMiCgpFRFVfSW5jb3Jwb3JhdGlvbl9QZXJjZW50YWdlJENvbmRpdGlvbiA8LSBmYWN0b3IoRURVX0luY29ycG9yYXRpb25fUGVyY2VudGFnZSRDb25kaXRpb24sIGMoIkNvbnRyb2wiLCAiYjVLRCIpKQoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgRURVX2JveHBsb3RfcGFuZWxfZmlsZV9uYW1lLCAiLnN2ZyIsIHNlcCA9ICIiKSwgd2lkdGg9NCwgaGVpZ2h0PTYpCgpib3hwbG90KFBlcmNlbnRhZ2UuRURVLnBvc2l0aXZlLkNlbGxzLnBlci5pbWFnZSB+IENvbmRpdGlvbiwgZGF0YSA9IEVEVV9JbmNvcnBvcmF0aW9uX1BlcmNlbnRhZ2UsIG5vdGNoID0gVCwgdmFyd2lkdGggPSBULCBvdXRsaW5lID0gRiwgeWxhYiA9ICIlIEVEVSBwb3NpdGl2ZSBjZWxscyIsIGNvbCA9IGMoY29udHJvbCA9ICIjNDk0OTRBIiwgYjVLRCA9ICIjRUMxQzI0IiksIHlsaW0gPSBjKDAsMTE1KSkKYmVlc3dhcm0oUGVyY2VudGFnZS5FRFUucG9zaXRpdmUuQ2VsbHMucGVyLmltYWdlIH4gQ29uZGl0aW9uLCBkYXRhID0gRURVX0luY29ycG9yYXRpb25fUGVyY2VudGFnZSwgbWV0aG9kID0gJ2NlbnRlcicsIGFkZCA9IFQsIGNvbCA9ICJzdGVlbGJsdWUyIiwgcGNoID0gMSwgY2V4ID0gMS4zKQoKZGV2Lm9mZigpCgpib3hwbG90KFBlcmNlbnRhZ2UuRURVLnBvc2l0aXZlLkNlbGxzLnBlci5pbWFnZSB+IENvbmRpdGlvbiwgZGF0YSA9IEVEVV9JbmNvcnBvcmF0aW9uX1BlcmNlbnRhZ2UsIG5vdGNoID0gVCwgdmFyd2lkdGggPSBULCBvdXRsaW5lID0gRiwgeWxhYiA9ICIlIEVEVSBwb3NpdGl2ZSBjZWxscyIsIGNvbCA9IGMoY29udHJvbCA9ICIjNDk0OTRBIiwgYjVLRCA9ICIjRUMxQzI0IiksIHlsaW0gPSBjKDAsMTE1KSkKYmVlc3dhcm0oUGVyY2VudGFnZS5FRFUucG9zaXRpdmUuQ2VsbHMucGVyLmltYWdlIH4gQ29uZGl0aW9uLCBkYXRhID0gRURVX0luY29ycG9yYXRpb25fUGVyY2VudGFnZSwgbWV0aG9kID0gJ2NlbnRlcicsIGFkZCA9IFQsIGNvbCA9ICJzdGVlbGJsdWUyIiwgcGNoID0gMSwgY2V4ID0gMS4zKQoKCmBgYAoKIyMjIyBGaWc2QiBNYW5uLVdoaXRuZXkgwrUgdGVzdCBmb3IgRURVIEluY29ycG9yYXRpb24gZGlmZmVyZW5jZXMKYGBge3IgTWFubi1XaGl0bmV5IMK1IHRlc3QgZm9yIEVEVSBJbmNvcnBvcmF0aW9uIGRpZmZlcmVuY2VzfQoKI05vdGU6IEVxdWl2YWxlbnQgdG8gV2lsY294b24gcmFuayBzdW0gdGVzdCBhcyBkYXRhIGlzIHVucGFpcmVkCgpVdGVzdC5iNUtELnZzLmNvbnRyb2xfRURVIDwtIHdpbGNveC50ZXN0KFBlcmNlbnRhZ2UuRURVLnBvc2l0aXZlLkNlbGxzLnBlci5pbWFnZSB+IENvbmRpdGlvbiwgZGF0YSA9IEVEVV9JbmNvcnBvcmF0aW9uX1BlcmNlbnRhZ2UpCk1hbm5fV2hpdG5leV9FRFVfSW5jb3Jwb3JhdGlvbl9TY29yZSA8LSBVdGVzdC5iNUtELnZzLmNvbnRyb2xfRURVJHAudmFsdWUKCnByaW50KE1hbm5fV2hpdG5leV9FRFVfSW5jb3Jwb3JhdGlvbl9TY29yZSkKCmBgYAoKCiMgRmlndXJlIDcKCiMjIEltcG9ydCBEYXRhIGZvciBGaWd1cmUgNwpgYGB7ciBtcG9ydCBEYXRhIGZvciBGaWd1cmUgN30KCiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCmRhdGFfaW5wdXRfcGF0aCA8LSAiL1VzZXJzL2pvaG5sb2NrL0Ryb3Bib3gvQS1DTUFDIE1hbmNoZXN0ZXIgY29sbGFib3JhdGlvbi9OQ0Igc3VibWlzc2lvbiBkb2N1bWVudHMvUmVzdWJtaXNzaW9uIDIvU291cmNlX0RhdGEiCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCiMgSW1wb3J0IGluZGl2aWR1YWwgZGF0YSBmaWxlcwoKU1RPUk0uRGF0YSA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzdFX0YiLCBjb2xfbmFtZXMgPSBUUlVFKQoKYGBgCgojIyBBbmFseXNpcyBvZiBtaXRvdGljIFNUT1JNIGRhdGEKCiMjIyBTVE9STSBkYXRhIHdyYW5nbGluZzIKYGBge3IgU1RPUk0gZGF0YSB3cmFuZ2xpbmcyfQojIyBEZXRlcm1pbmUgQ01BQy50eXBlIChSZXRpY3VsYXIgdnMgRm9jYWwgZGVwZW5kaW5nIG9uIHByZXNlbmNlIG9mIEEgaW4gJEZpbGUgKGNvbHVtbikpCgpDTUFDLnR5cGUgPSBjKCkKZm9yIChjbHVzdGVyIGluIDE6bGVuZ3RoKFNUT1JNLkRhdGEkRmlsZSkgKSB7CiAgQ01BQy50eXBlW2NsdXN0ZXJdIDwtIGlmKGdyZXBsKCJBIiwgU1RPUk0uRGF0YSRGaWxlW2NsdXN0ZXJdKSA9PSBUUlVFKSB7CiAgICAiUmV0aWN1bGFyIgogIH0gZWxzZSBpZihncmVwbCgiVCIsIFNUT1JNLkRhdGEkRmlsZVtjbHVzdGVyXSkgPT0gVFJVRSkgewogICAgIkZvY2FsIgogIH0gZWxzZSBpZihncmVwbCgiTlIiLCBTVE9STS5EYXRhJEZpbGVbY2x1c3Rlcl0pID09IFRSVUUpIHsKICAgICJOb24tUmV0cmFjdGlvbiIKICB9IGVsc2UgewogICAgIlJldHJhY3Rpb24iCiAgfQp9CgpTVE9STS5EYXRhJENNQUMudHlwZSA8LSBjYmluZChhcy5jaGFyYWN0ZXIoQ01BQy50eXBlKSkKCiMjIFVuaXF1ZSBuYW5vY2x1c3RlciBJRCBnZW5lcmF0aW9uID0gbWVyZ2Ugb2YgRm9sZGVyLCBGaWxlIGFuZCBDbHVzdGVyCgpTVE9STS5EYXRhJFVuaXF1ZS5uY0lEIDwtIGFzLmZhY3RvcihwYXN0ZShTVE9STS5EYXRhJEZvbGRlciwgU1RPUk0uRGF0YSRGaWxlLCBTVE9STS5EYXRhJENsdXN0ZXIpKQpTVE9STS5EYXRhJFVuaXF1ZS5DTUFDSUQgPC0gYXMuZmFjdG9yKHBhc3RlKFNUT1JNLkRhdGEkRm9sZGVyLCBTVE9STS5EYXRhJEZpbGUpKQpgYGAKCiMjIyBOZWFyZXN0IE5laWdoYm91ciBBbmFseXNpcyBiZXR3ZWVuIGxvY2FsaXNhdGlvbnMgd2l0aGluIHVuaXF1ZSBuYW5vY2x1c3RlcnMyCmBgYHtyIE5lYXJlc3QgTmVpZ2hib3VyIEFuYWx5c2lzIGJldHdlZW4gbG9jYWxpc2F0aW9ucyB3aXRoaW4gdW5pcXVlIG5hbm9jbHVzdGVyczJ9CiMjIE5ORCBhbmFseXNpcyBvZiBJbmNpdGUzIGRhdGEKCk5OTkQgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoU1RPUk0uRGF0YSRVbmlxdWUuQ01BQ0lEKSkgKSB7CiAgdGVtcCA9IFNUT1JNLkRhdGFbU1RPUk0uRGF0YSRVbmlxdWUuQ01BQ0lEID09IHVuaXF1ZShTVE9STS5EYXRhJFVuaXF1ZS5DTUFDSUQpW2ldLCBdCiAgTk5ORCA9IGFwcGVuZChOTk5ELCBubmRpc3QodGVtcCRDZW50cm9pZC5ubS4sIHRlbXAkQ2VudHJvaWQubm0uLjEsIGs9MSkpCn0KClNUT1JNLkRhdGEkTk5ORCA8LSBjYmluZChOTk5EKQpgYGAKCiMjIyBCb3hwbG90cyBzdW1tYXJpc2luZyBOZWFyZXN0IE5laWdoYm91dCBEaXN0YW5jZSBwZXIgbmFub2NsdXN0ZXIyCmBgYHtyIEJveHBsb3RzIHN1bW1hcmlzaW5nIE5lYXJlc3QgTmVpZ2hib3V0IERpc3RhbmNlIHBlciBuYW5vY2x1c3RlcjJ9CgpOTk5ELkEgPSBzdWJzZXQoU1RPUk0uRGF0YSROTk5ELCBDTUFDLnR5cGUgPT0gIk5vbi1SZXRyYWN0aW9uIikKCk5OTkQuVCA9IHN1YnNldChTVE9STS5EYXRhJE5OTkQsIENNQUMudHlwZSA9PSAiUmV0cmFjdGlvbiIpCgoKVEVTVF9ubm5kX05SdnNSIDwtIHdpbGNveC50ZXN0KE5OTkQuQSwgTk5ORC5ULCBwYWlyZWQgPSBGQUxTRSkKCk5OTkRfYm94cGxvdF9maWxlbmFtZSA8LSAiUGFuZWwgN0UgTk5ORCBib3hwbG90IgoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgTk5ORF9ib3hwbG90X2ZpbGVuYW1lLCAiLnN2ZyIsIHNlcCA9ICIiKSwgd2lkdGg9NCwgaGVpZ2h0PTMpCgpib3hwbG90KE5OTkQgfiBDTUFDLnR5cGUsIHN1YnNldChTVE9STS5EYXRhLCBDTUFDLnR5cGUgPT0gIk5vbi1SZXRyYWN0aW9uIiB8IENNQUMudHlwZSA9PSAiUmV0cmFjdGlvbiIpLCBub3RjaCA9IFRSVUUsIG91dGxpbmUgPSBGQUxTRSwKICAgICAgICBtYWluID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIG9mIE5hbm9jbHVzdGVyIGJ5IENNQUMgVHlwZSIsCiAgICAgICAgc3ViID0gVEVTVF9ubm5kX05SdnNSJHAudmFsdWUsCiAgICAgICAgeGxhYiA9ICJDTUFDIHR5cGUiLCAKICAgICAgICB5bGFiID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIChubSkiLAogICAgICAgIHBsb3QgPSAiVFJVRSIKKQoKZGV2Lm9mZigpCgpib3hwbG90KE5OTkQgfiBDTUFDLnR5cGUsIHN1YnNldChTVE9STS5EYXRhLCBDTUFDLnR5cGUgPT0gIk5vbi1SZXRyYWN0aW9uIiB8IENNQUMudHlwZSA9PSAiUmV0cmFjdGlvbiIpLCBub3RjaCA9IFRSVUUsIG91dGxpbmUgPSBGQUxTRSwKICAgICAgICBtYWluID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIG9mIE5hbm9jbHVzdGVyIGJ5IENNQUMgVHlwZSIsCiAgICAgICAgc3ViID0gVEVTVF9ubm5kX05SdnNSJHAudmFsdWUsCiAgICAgICAgeGxhYiA9ICJDTUFDIHR5cGUiLCAKICAgICAgICB5bGFiID0gIk5lYXJlc3QgTmVpZ2hib3VyIERpc3RhbmNlIChubSkiLAogICAgICAgIHBsb3QgPSAiVFJVRSIKKQpgYGAKCiMjIyBCb3hwbG90cyBzdW1tYXJpc2luZyBNb2xlY3VsYXIgTG9jYWxpemF0aW9uIHBlciBuYW5vY2x1c3RlcjIKYGBge3IgQm94cGxvdHMgc3VtbWFyaXNpbmcgTW9sZWN1bGFyIExvY2FsaXphdGlvbiBwZXIgbmFub2NsdXN0ZXIyfQpTVE9STS5EYXRhJE1vbGVjdWxlcyA8LSBhcy5udW1lcmljKFNUT1JNLkRhdGEkTW9sZWN1bGVzKQoKTW9sZWN1bGVzLkEgPSBzdWJzZXQoU1RPUk0uRGF0YSRNb2xlY3VsZXMsIENNQUMudHlwZSA9PSAiTm9uLVJldHJhY3Rpb24iKQoKTW9sZWN1bGVzLlQgPSBzdWJzZXQoU1RPUk0uRGF0YSRNb2xlY3VsZXMsIENNQUMudHlwZSA9PSAiUmV0cmFjdGlvbiIpCgoKTW9sX0NvdW50X2JveHBsb3RfZmlsZW5hbWUgPC0gIlBhbmVsIDdGIE1vbGVjdWxlIENvdW50IGJveHBsb3QiCgpzdmdsaXRlKHBhc3RlKHBhbmVsX291dHB1dF9wYXRoLCBNb2xfQ291bnRfYm94cGxvdF9maWxlbmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTQsIGhlaWdodD0zKQoKVEVTVF9Nb2xlY3VsZXMuQV9SZXR2c0ZvYyA8LSB3aWxjb3gudGVzdChNb2xlY3VsZXMuQSwgTW9sZWN1bGVzLlQsIHBhaXJlZCA9IEZBTFNFKQpib3hwbG90KE1vbGVjdWxlcyB+IENNQUMudHlwZSwgc3Vic2V0KFNUT1JNLkRhdGEsIENNQUMudHlwZSA9PSAiTm9uLVJldHJhY3Rpb24iIHwgQ01BQy50eXBlID09ICJSZXRyYWN0aW9uIiksIG5vdGNoID0gVFJVRSxvdXRsaW5lID0gRkFMU0UsCiAgICAgICAgbWFpbiA9ICJOdW1iZXIgb2YgSW50ZWdyaW4gYXZiNSBNb2xlY3VsZXMgYnkgQ01BQyBUeXBlIiwKICAgICAgICBzdWIgPSBURVNUX01vbGVjdWxlcy5BX1JldHZzRm9jJHAudmFsdWUsCiAgICAgICAgeGxhYiA9ICJDTUFDIHR5cGUiLCAKICAgICAgICB5bGFiID0gIk51bWJlciBvZiBJbnRlZ3JpbiBhdmI1IE1vbGVjdWxlcyIsCiAgICAgICAgcGxvdCA9ICJUUlVFIgogICAgICAgICkKCmRldi5vZmYoKQoKVEVTVF9Nb2xlY3VsZXMuQV9SZXR2c0ZvYyA8LSB3aWxjb3gudGVzdChNb2xlY3VsZXMuQSwgTW9sZWN1bGVzLlQsIHBhaXJlZCA9IEZBTFNFKQpib3hwbG90KE1vbGVjdWxlcyB+IENNQUMudHlwZSwgc3Vic2V0KFNUT1JNLkRhdGEsIENNQUMudHlwZSA9PSAiTm9uLVJldHJhY3Rpb24iIHwgQ01BQy50eXBlID09ICJSZXRyYWN0aW9uIiksIG5vdGNoID0gVFJVRSxvdXRsaW5lID0gRkFMU0UsCiAgICAgICAgbWFpbiA9ICJOdW1iZXIgb2YgSW50ZWdyaW4gYXZiNSBNb2xlY3VsZXMgYnkgQ01BQyBUeXBlIiwKICAgICAgICBzdWIgPSBURVNUX01vbGVjdWxlcy5BX1JldHZzRm9jJHAudmFsdWUsCiAgICAgICAgeGxhYiA9ICJDTUFDIHR5cGUiLCAKICAgICAgICB5bGFiID0gIk51bWJlciBvZiBJbnRlZ3JpbiBhdmI1IE1vbGVjdWxlcyIsCiAgICAgICAgcGxvdCA9ICJUUlVFIgogICAgICAgICkKCmBgYAoKIyBGaWd1cmUgOAoKIyMgSW1wb3J0IERhdGEgZm9yIEZpZ3VyZSA4CmBgYHtyIG1wb3J0IERhdGEgZm9yIEZpZ3VyZSA4fQoKIyBTZXQgeW91ciBwYXRoIHRvIGlucHV0IGRhdGEKZGF0YV9pbnB1dF9wYXRoIDwtICIvVXNlcnMvam9obmxvY2svRHJvcGJveC9BLUNNQUMgTWFuY2hlc3RlciBjb2xsYWJvcmF0aW9uL05DQiBzdWJtaXNzaW9uIGRvY3VtZW50cy9SZXN1Ym1pc3Npb24gMi9Tb3VyY2VfRGF0YSIKZGF0YV9maWxlIDwtICJTdXBwbGVtZW50YXJ5IFRhYmxlIDEgU3RhdGlzdGljcyBTb3VyY2UgRGF0YS54bHN4IgoKIyBJbXBvcnQgaW5kaXZpZHVhbCBkYXRhIGZpbGVzCgpSZXNpZHVhbF9BbmdsZV9kYXRhIDwtIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiRmlnOEFfQiIsIGNvbF9uYW1lcyA9IFRSVUUpCgpDZWxsX0RpdmlzaW9uX0RlZmVjdF9RdWFudGlmaWNhdGlvbiA8LSByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIkZpZzhDIiwgY29sX25hbWVzID0gVFJVRSkKQ2VsbF9EaXZpc2lvbl9EZWZlY3RfUXVhbnRpZmljYXRpb24gPC0gQ2VsbF9EaXZpc2lvbl9EZWZlY3RfUXVhbnRpZmljYXRpb25bMTo5LCAxOjRdCgpgYGAKCiMjIFJlc2lkdWFsIEFuZ2xlIENvbXBhcmlzb25zIHBlciBDb25kaXRpb24KIyMjIEZpZyA4QSBQbG90IFJlc2lkdWFsIEFuZ2xlIEJveHBsb3Qgb2YgKy8tIEJlZXN3YXJtIGJ5IGNvbmRpdGlvbgpgYGB7ciBQbG90IFJlc2lkdWFsIEFuZ2xlIEJveHBsb3QgYnkgY29uZGl0aW9ufQoKI2RlZmluZSBwYW5lbF9maWxlX25hbWUKYm94cGxvdF9wYW5lbF9maWxlX25hbWUgPC0gIlBhbmVsIDhBIFJlc2lkdWFsIEFuZ2xlIEJveHBsb3RzIgoKIyBvbGRwYXIgPC0gcGFyKCkKIyBwYXIobWZyb3cgPSBjKDEsMSksIG1hciA9IGMoNSw1LDEsMSkpCgpSZXNpZHVhbF9BbmdsZV9kYXRhQ04gPC0gUmVzaWR1YWxfQW5nbGVfZGF0YQoKIyBTZXQgQ29uZGl0aW9uIG9yZGVyClJlc2lkdWFsX0FuZ2xlX2RhdGFDTiRDb25kaXRpb24gPC0gZmFjdG9yKFJlc2lkdWFsX0FuZ2xlX2RhdGFDTiRDb25kaXRpb24sIGMoIkNvbnRyb2wiLCAiYjVLRCIsICJSZXNjdWUiKSkKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIGJveHBsb3RfcGFuZWxfZmlsZV9uYW1lLCAiLnN2ZyIsIHNlcCA9ICIiKSwgd2lkdGg9NCwgaGVpZ2h0PTYpCgpib3hwbG90KFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBDb25kaXRpb24sIGRhdGEgPSBSZXNpZHVhbF9BbmdsZV9kYXRhQ04sIG5vdGNoID0gVCwgdmFyd2lkdGggPSBULCBvdXRsaW5lID0gRiwgeWxhYiA9ICJSZXNpZHVhbCBBbmdsZSIsIGNvbCA9IGMoY29udHJvbCA9ICIjNDk0OTRBIiwgYjVLRCA9ICIjRUMxQzI0IiwgUmVzY3VlID0gIiNCQ0JDQkMiKSwgeWxpbSA9IGMoMCwxMTUpKQpiZWVzd2FybShQcmUudG8uUG9zdC5NaXRvc2lzLkFuZ2xlIH4gQ29uZGl0aW9uLCBkYXRhID0gUmVzaWR1YWxfQW5nbGVfZGF0YUNOLCBtZXRob2QgPSAnY2VudGVyJywgYWRkID0gVCwgY29sID0gInN0ZWVsYmx1ZTIiLCBwY2ggPSAxLCBjZXggPSAwLjUpCgpkZXYub2ZmKCkKCmJveHBsb3QoUHJlLnRvLlBvc3QuTWl0b3Npcy5BbmdsZSB+IENvbmRpdGlvbiwgZGF0YSA9IFJlc2lkdWFsX0FuZ2xlX2RhdGFDTiwgbm90Y2ggPSBULCB2YXJ3aWR0aCA9IFQsIG91dGxpbmUgPSBGLCB5bGFiID0gIlJlc2lkdWFsIEFuZ2xlIiwgY29sID0gYyhjb250cm9sID0gIiM0OTQ5NEEiLCBiNUtEID0gIiNFQzFDMjQiLCBSZXNjdWUgPSAiI0JDQkNCQyIpLCB5bGltID0gYygwLDExNSkpCmJlZXN3YXJtKFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBDb25kaXRpb24sIGRhdGEgPSBSZXNpZHVhbF9BbmdsZV9kYXRhQ04sIG1ldGhvZCA9ICdjZW50ZXInLCBhZGQgPSBULCBjb2wgPSAic3RlZWxibHVlMiIsIHBjaCA9IDEsIGNleCA9IDAuNSkKCmBgYAoKCiMjIyBGaWcgOEIgUGxvdCBSZXNpZHVhbCBBbmdsZSBzbW9vdGhlZCBkZW5zaXR5IHBsb3QgcGVyIGNvbmRpdGlvbgpgYGB7ciBQbG90IFJlc2lkdWFsIEFuZ2xlIHNtb290aGVkIGRlbnNpdHkgcGxvdCBwZXIgY29uZGl0aW9ufQoKI2RlZmluZSBwYW5lbF9maWxlX25hbWUKZGVuc2l0eV9wYW5lbF9maWxlX25hbWUgPC0gIlBhbmVsIDhCIFJlc2lkdWFsIEFuZ2xlIERlbnNpdHkgUGxvdCIKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIGRlbnNpdHlfcGFuZWxfZmlsZV9uYW1lLCAiLnN2ZyIsIHNlcCA9ICIiKSwgd2lkdGg9NCwgaGVpZ2h0PTYpCgpzbS5kZW5zaXR5LmNvbXBhcmUoUmVzaWR1YWxfQW5nbGVfZGF0YUNOJFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUsIFJlc2lkdWFsX0FuZ2xlX2RhdGFDTiRDb25kaXRpb24sIGNvbCA9IGMoIiM0OTQ5NEEiLCAiI0VDMUMyNCIsICIjQkNCQ0JDIiksIGx0eSA9IGMoMSwxLDEpLCBsd2QgPSAyLCBoID0gNSwgeGxpbSA9IGMoMCw5MCksIHhsYWIgPSAiUmVzaWR1YWwgQW5nbGUiKQpjb2xmaWxsPC1jKCIjNDk0OTRBIiwgIiNFQzFDMjQiLCAiI0JDQkNCQyIpCmxlZ2VuZCh4PTQwLCB5PTAuMDMzLCBsZXZlbHMoUmVzaWR1YWxfQW5nbGVfZGF0YUNOJENvbmRpdGlvbiksIGZpbGw9Y29sZmlsbCwgYnR5ID0gIm4iKQoKZGV2Lm9mZigpCgpzbS5kZW5zaXR5LmNvbXBhcmUoUmVzaWR1YWxfQW5nbGVfZGF0YUNOJFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUsIFJlc2lkdWFsX0FuZ2xlX2RhdGFDTiRDb25kaXRpb24sIGNvbCA9IGMoIiM0OTQ5NEEiLCAiI0VDMUMyNCIsICIjQkNCQ0JDIiksIGx0eSA9IGMoMSwxLDEpLCBsd2QgPSAyLCBoID0gNSwgeGxpbSA9IGMoMCw5MCksIHhsYWIgPSAiUmVzaWR1YWwgQW5nbGUiKQpjb2xmaWxsPC1jKCIjNDk0OTRBIiwgIiNFQzFDMjQiLCAiI0JDQkNCQyIpCmxlZ2VuZCh4PTQwLCB5PTAuMDMzLCBsZXZlbHMoUmVzaWR1YWxfQW5nbGVfZGF0YUNOJENvbmRpdGlvbiksIGZpbGw9Y29sZmlsbCwgYnR5ID0gIm4iKQoKYGBgCgojIyMjIENvdW50IGNlbGwgbnVtYmVyIHBlciBjb25kaXRpb24KYGBge3IgQ291bnQgY2VsbCBudW1iZXIgcGVyIGNvbmRpdGlvbn0KUmVzaWR1YWxfQW5nbGVfZGF0YUNOICU+JQogIGdyb3VwX2J5KENvbmRpdGlvbikgJT4lCiAgc3VtbWFyaXNlKAogICAgbiA9IG4oKSkKYGBgCgoKIyMjIyBNYW5uLVdoaXRuZXkgwrUgdGVzdCBmb3IgUmVzaWR1YWwgQW5nbGUgZGlmZmVyZW5jZXMKYGBge3IgTWFubi1XaGl0bmV5IMK1IHRlc3QgZm9yIFJlc2lkdWFsIEFuZ2xlIGRpZmZlcmVuY2VzfQoKI05vdGU6IEVxdWl2YWxlbnQgdG8gV2lsY294b24gcmFuayBzdW0gdGVzdCBhcyBkYXRhIGlzIHVucGFpcmVkCgpiNUtEX0NvbnRyb2wgPC0gc3Vic2V0KFJlc2lkdWFsX0FuZ2xlX2RhdGEsIFJlc2lkdWFsX0FuZ2xlX2RhdGEkQ29uZGl0aW9uID09ICJiNUtEIiB8IFJlc2lkdWFsX0FuZ2xlX2RhdGEkQ29uZGl0aW9uID09ICJDb250cm9sIikKVXRlc3QuYjVLRC52cy5jb250cm9sIDwtIHdpbGNveC50ZXN0KFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBDb25kaXRpb24sIGRhdGEgPSBiNUtEX0NvbnRyb2wpClV0ZXN0LmI1S0QudnMuY29udHJvbC5wdmFsIDwtIFV0ZXN0LmI1S0QudnMuY29udHJvbCRwLnZhbHVlCgpiNUtEX1Jlc2N1ZSA8LSBzdWJzZXQoUmVzaWR1YWxfQW5nbGVfZGF0YSwgUmVzaWR1YWxfQW5nbGVfZGF0YSRDb25kaXRpb24gPT0gImI1S0QiIHwgUmVzaWR1YWxfQW5nbGVfZGF0YSRDb25kaXRpb24gPT0gIlJlc2N1ZSIpClV0ZXN0LmI1S0QudnMuUmVzY3VlIDwtIHdpbGNveC50ZXN0KFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBDb25kaXRpb24sIGRhdGEgPSBiNUtEX1Jlc2N1ZSkKVXRlc3QuYjVLRC52cy5SZXNjdWUucHZhbCA8LSBVdGVzdC5iNUtELnZzLlJlc2N1ZSRwLnZhbHVlCgpDb250cm9sX1Jlc2N1ZSA8LSBzdWJzZXQoUmVzaWR1YWxfQW5nbGVfZGF0YSwgUmVzaWR1YWxfQW5nbGVfZGF0YSRDb25kaXRpb24gPT0gIkNvbnRyb2wiIHwgUmVzaWR1YWxfQW5nbGVfZGF0YSRDb25kaXRpb24gPT0gIlJlc2N1ZSIpClV0ZXN0LmNvbnRyb2wudnMuUmVzY3VlIDwtIHdpbGNveC50ZXN0KFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBDb25kaXRpb24sIGRhdGEgPSBDb250cm9sX1Jlc2N1ZSkKVXRlc3QuY29udHJvbC52cy5SZXNjdWUucHZhbCA8LSBVdGVzdC5jb250cm9sLnZzLlJlc2N1ZSRwLnZhbHVlCgpNYW5uX1doaXRuZXlfU2NvcmVzIDwtIGRhdGEuZnJhbWUoQ29uZGl0aW9uX0NvbXBhcmlzb24gPSBjKCJiNUtEX3ZzX0NvbnRyb2wiLCAiYjVLRF92c19SZXNjdWUiLCAiQ29udHJvbF92c19SZXNjdWUiKSkKTWFubl9XaGl0bmV5X1Njb3JlcyRwdmFsdWUgPC0gcmJpbmQoVXRlc3QuYjVLRC52cy5jb250cm9sLnB2YWwsIFV0ZXN0LmI1S0QudnMuUmVzY3VlLnB2YWwsIFV0ZXN0LmNvbnRyb2wudnMuUmVzY3VlLnB2YWwpCgpwcmludChNYW5uX1doaXRuZXlfU2NvcmVzKQoKYGBgCgojIyBSZXNpZHVhbCBBbmdsZSBDb21wYXJpc29ucyBwZXIgQ29uZGl0aW9uIHBlciBFeHBlcmltZW50CiMjIyBQbG90IFJlc2lkdWFsIEFuZ2xlIEJveHBsb3QgYnkgY29uZGl0aW9uIGJ5IGV4cGVyaW1lbnQKYGBge3IgUGxvdCBSZXNpZHVhbCBBbmdsZSBCb3hwbG90IGJ5IGNvbmRpdGlvbiBieSBleHBlcmltZW50fQpSZXNpZHVhbF9BbmdsZV9kYXRhRk4gPC0gUmVzaWR1YWxfQW5nbGVfZGF0YQoKUmVzaWR1YWxfQW5nbGVfZGF0YUZOJEZpbGUuTmFtZSA8LSBmYWN0b3IoUmVzaWR1YWxfQW5nbGVfZGF0YUZOJEZpbGUuTmFtZSwgYygiXzNfTU1TdGFja19jb250cm9sIEhlbGEgMDEub21lLnRpZiIsICJfM19NTVN0YWNrX2NvbnRyb2wgSGVsYSAwMi5vbWUudGlmIiwgIl8zX01NU3RhY2tfYjUgS0QgcGx1cyBHRlAgMDEub21lLnRpZiIsICJfM19NTVN0YWNrX2I1IEtEIHBsdXMgR0ZQIDAyLm9tZS50aWYiLCAiXzNfTU1TdGFja19iNSBLRCBwbHVzIFdUYjUtR0ZQIDAxLm9tZS50aWYiLCAiXzNfTU1TdGFja19iNSBLRCBwbHVzIFdUYjUtR0ZQIDAyLm9tZS50aWYiKSkKCgpib3hwbG90KFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBGaWxlLk5hbWUsIGRhdGEgPSBSZXNpZHVhbF9BbmdsZV9kYXRhRk4sIG5vdGNoID0gVCwgdmFyd2lkdGggPSBULCBvdXRsaW5lID0gRiwgeWxhYiA9ICJSZXNpZHVhbCBBbmdsZSIsIGNvbCA9IGMoIiM0OTQ5NEEiLCAiIzQ5NDk0QSIsICIjRUMxQzI0IiwgIiNFQzFDMjQiLCIjQkNCQ0JDIiwgIiNCQ0JDQkMiKSwgeWxpbSA9IGMoMCwxMTUpLCBuYW1lcyA9IGMoIkN0cmxfMDEiLCAiQ3RybF8wMiIsICJiNUtEXzAxIiwgImI1S0RfMDIiLCAiUmVzY18wMSIsICJSZXNjXzAyIikpCgojIGJlZXN3YXJtKFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUgfiBGaWxlLk5hbWUsIGRhdGEgPSBSZXNpZHVhbF9BbmdsZV9kYXRhRk4sIG1ldGhvZCA9ICdzd2FybScsIGFkZCA9IFQsIGNvbCA9ICJzdGVlbGJsdWUyIiwgcGNoID0gMCwgY2V4ID0gMC43KQoKYGBgCgojIyMgUGxvdCBQbG90IFJlc2lkdWFsIEFuZ2xlIHNtb290aGVkIGRlbnNpdHkgcGxvdCBwZXIgY29uZGl0aW9uIHBlciBleHBlcmltZW50CmBgYHtyIFBsb3QgUmVzaWR1YWwgQW5nbGUgc21vb3RoZWQgZGVuc2l0eSBwbG90IHBlciBjb25kaXRpb24gcGVyIGV4cGVyaW1lbnR9CgpzbS5kZW5zaXR5LmNvbXBhcmUoUmVzaWR1YWxfQW5nbGVfZGF0YUZOJFByZS50by5Qb3N0Lk1pdG9zaXMuQW5nbGUsIFJlc2lkdWFsX0FuZ2xlX2RhdGFGTiRGaWxlLk5hbWUsIGNvbCA9IGMoIiM0OTQ5NEEiLCAiIzQ5NDk0QSIsICIjRUMxQzI0IiwgIiNFQzFDMjQiLCIjQkNCQ0JDIiwiI0JDQkNCQyIpLCBoPTUsIGx0eSA9IGMoMSw1LDEsNSwxLDUpLCBsd2QgPSAyLCB4bGltID0gYygwLDkwKSwgeGxhYiA9ICJSZXNpZHVhbCBBbmdsZSIpCmxlZ2VuZCh4PTIzLCB5PSAwLjA1LCBsZXZlbHMoUmVzaWR1YWxfQW5nbGVfZGF0YUZOJEZpbGUuTmFtZSksIGZpbGw9YygiIzQ5NDk0QSIsICIjNDk0OTRBIiwgIiNFQzFDMjQiLCAiI0VDMUMyNCIsIiNCQ0JDQkMiLCIjQkNCQ0JDIiksIGJ0eSA9ICduJykKCmBgYAojIyMjIENvdW50IGNlbGwgbnVtYmVyIHBlciBjb25kaXRpb24gcGVyIGV4cGVyaW1lbnQKYGBge3IgQ291bnQgY2VsbCBudW1iZXIgcGVyIGNvbmRpdGlvbiBwZXIgZXhwZXJpbWVudH0KUmVzaWR1YWxfQW5nbGVfZGF0YUZOICU+JQogIGdyb3VwX2J5KEZpbGUuTmFtZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbiA9IG4oKSkKYGBgCgoKCiMjIENlbGwgRGl2aXNpb24gRGVmZWN0IFF1YW50aWZpY2F0aW9uCiMjIyBGaWcgOEMgQ2VsbCBEaXZpc2lvbiBEZWZlY3QgUmF0ZSBQbG90dGluZwpgYGB7ciBDZWxsIERpdmlzaW9uIERlZmVjdCBSYXRlIFBsb3R0aW5nfQoKQ0REX2JveHBsb3RfcGFuZWxfZmlsZV9uYW1lIDwtICJQYW5lbCA4QyBDZWxsIERpdmlzaW9uIERlZmVjdCBSYXRlIEJveHBsb3QiCgpDZWxsX0RpdmlzaW9uX0RlZmVjdF9RdWFudGlmaWNhdGlvbiRDb25kaXRpb24gPC0gZmFjdG9yKENlbGxfRGl2aXNpb25fRGVmZWN0X1F1YW50aWZpY2F0aW9uJENvbmRpdGlvbiwgYygiQ29udHJvbCIsICJiNUtEIiwgIlJlc2N1ZSIpKQoKc3ZnbGl0ZShwYXN0ZShwYW5lbF9vdXRwdXRfcGF0aCwgQ0REX2JveHBsb3RfcGFuZWxfZmlsZV9uYW1lLCAiLnN2ZyIsIHNlcCA9ICIiKSwgd2lkdGg9NCwgaGVpZ2h0PTYpCgpib3hwbG90KG5vcm1hbC5jZWxsLmRpdmlzaW9uIH4gQ29uZGl0aW9uLCBkYXRhID0gQ2VsbF9EaXZpc2lvbl9EZWZlY3RfUXVhbnRpZmljYXRpb24sIG91dGxpbmUgPSBGQUxTRSwgYm94bHR5ID0gMCwgd2hpc2tsdHkgPSAwLCBzdGFwbGVsdHkgPSAwLCB5bGFiID0gIk5vcm1hbCBEaXZpc2lvbiBQZXJjZW50YWdlIiwgeWxpbSA9IGMoMCwxMTUpLCBtZWRsd2QgPSAwLjApCmJlZXN3YXJtKG5vcm1hbC5jZWxsLmRpdmlzaW9uIH4gQ29uZGl0aW9uLCBkYXRhID0gQ2VsbF9EaXZpc2lvbl9EZWZlY3RfUXVhbnRpZmljYXRpb24sIG1ldGhvZCA9ICdjZW50ZXInLCBhZGQgPSBULCBjb2wgPSBjKGNvbnRyb2wgPSAiIzQ5NDk0QSIsIGI1S0QgPSAiI0VDMUMyNCIsIFJlc2N1ZSA9ICIjQkNCQ0JDIiksIHlsaW0gPSBjKDAsMTE1KSwgcGNoID0gMTksIGNleCA9IDEuMykKCmRldi5vZmYoKQoKYm94cGxvdChub3JtYWwuY2VsbC5kaXZpc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IENlbGxfRGl2aXNpb25fRGVmZWN0X1F1YW50aWZpY2F0aW9uLCBvdXRsaW5lID0gRkFMU0UsIGJveGx0eSA9IDAsIHdoaXNrbHR5ID0gMCwgc3RhcGxlbHR5ID0gMCwgeWxhYiA9ICJOb3JtYWwgRGl2aXNpb24gUGVyY2VudGFnZSIsIHlsaW0gPSBjKDAsMTE1KSwgbWVkbHdkID0gMC4wKQpiZWVzd2FybShub3JtYWwuY2VsbC5kaXZpc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IENlbGxfRGl2aXNpb25fRGVmZWN0X1F1YW50aWZpY2F0aW9uLCBtZXRob2QgPSAnY2VudGVyJywgYWRkID0gVCwgY29sID0gYyhjb250cm9sID0gIiM0OTQ5NEEiLCBiNUtEID0gIiNFQzFDMjQiLCBSZXNjdWUgPSAiI0JDQkNCQyIpLCB5bGltID0gYygwLDExNSksIHBjaCA9IDE5LCBjZXggPSAxLjMpCgpgYGAKCiMjIyMgQ2VsbCBEaXZpc2lvbiBEZWZlY3QgU3VtbWFyaWVzIApgYGB7ciBDZWxsIERpdmlzaW9uIERlZmVjdCBRdWFudGlmaWNhdGlvbn0KCkRpdmlzaW9uX0RlZmVjdF9TdW1tYXJ5IDwtIENlbGxfRGl2aXNpb25fRGVmZWN0X1F1YW50aWZpY2F0aW9uICU+JQogIGdyb3VwX2J5KENvbmRpdGlvbikgJT4lCiAgc3VtbWFyaXNlKAogICAgTm9ybWFsX0RpdmlzaW9uID0gbWVhbihub3JtYWwuY2VsbC5kaXZpc2lvbiksCiAgICBBYm5vcm1hbF9EaXZpc2lvbiA9IG1lYW4oYWJub3JtYWwuY2VsbC5kaXZpc2lvbikKICApCiAKcHJpbnQoRGl2aXNpb25fRGVmZWN0X1N1bW1hcnkpICAgCgpgYGAKCiMjIyMgVC10ZXN0aW5nIGZvciBDZWxsIERpdmlzaW9uIERlZmVjdCBSYXRlIGRpZmZlcmVuY2VzCmBgYHtyIFQtdGVzdGluZyBmb3IgQ2VsbCBEaXZpc2lvbiBEZWZlY3QgUmF0ZXMgZGlmZmVyZW5jZXN9CgpiNUtEX0NvbnRyb2xfQ0REIDwtIHN1YnNldChDZWxsX0RpdmlzaW9uX0RlZmVjdF9RdWFudGlmaWNhdGlvbiwgQ29uZGl0aW9uID09ICJiNUtEIiB8IENvbmRpdGlvbiA9PSAiQ29udHJvbCIpClRfdGVzdF9iNUtEX0NvbnRyb2xfQ0REIDwtIHQudGVzdChub3JtYWwuY2VsbC5kaXZpc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IGI1S0RfQ29udHJvbF9DREQpJHAudmFsdWUKCmI1S0RfUmVzY3VlX0NERCA8LSBzdWJzZXQoQ2VsbF9EaXZpc2lvbl9EZWZlY3RfUXVhbnRpZmljYXRpb24sIENvbmRpdGlvbiA9PSAiYjVLRCIgfCBDb25kaXRpb24gPT0gIlJlc2N1ZSIpClRfdGVzdF9iNUtEX1Jlc2N1ZV9DREQgPC0gdC50ZXN0KG5vcm1hbC5jZWxsLmRpdmlzaW9uIH4gQ29uZGl0aW9uLCBkYXRhID0gYjVLRF9SZXNjdWVfQ0REKSRwLnZhbHVlCgpDb250cm9sX1Jlc2N1ZV9DREQgPC0gc3Vic2V0KENlbGxfRGl2aXNpb25fRGVmZWN0X1F1YW50aWZpY2F0aW9uLCBDb25kaXRpb24gPT0gIkNvbnRyb2wiIHwgQ29uZGl0aW9uID09ICJSZXNjdWUiKQpUX3Rlc3RfQ29udHJvbF9SZXNjdWVfQ0REIDwtIHQudGVzdChub3JtYWwuY2VsbC5kaXZpc2lvbiB+IENvbmRpdGlvbiwgZGF0YSA9IENvbnRyb2xfUmVzY3VlX0NERCkkcC52YWx1ZQoKVHRlc3RfU2NvcmVzX0NERCA8LSBkYXRhLmZyYW1lKENvbmRpdGlvbl9Db21wYXJpc29uID0gYygiYjVLRF9Db250cm9sX0NERCIsICJiNUtEX1Jlc2N1ZV9DREQiLCAiQ29udHJvbF9SZXNjdWVfQ0REIikpClR0ZXN0X1Njb3Jlc19DREQkcHZhbHVlIDwtIHJiaW5kKFRfdGVzdF9iNUtEX0NvbnRyb2xfQ0RELCBUX3Rlc3RfYjVLRF9SZXNjdWVfQ0RELCBUX3Rlc3RfQ29udHJvbF9SZXNjdWVfQ0REKQoKcHJpbnQoVHRlc3RfU2NvcmVzX0NERCkKCmBgYAoKIyBTdXBwIEZpZyA1CgojIyBJbXBvcnQgRGF0YSBTdXBwIEZpZyA1CmBgYHtyIEltcG9ydCBEYXRhIFN1cHAgRmlnIDV9CiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCmRhdGFfaW5wdXRfcGF0aCA8LSAiL1VzZXJzL2pvaG5sb2NrL0Ryb3Bib3gvQS1DTUFDIE1hbmNoZXN0ZXIgY29sbGFib3JhdGlvbi9OQ0Igc3VibWlzc2lvbiBkb2N1bWVudHMvUmVzdWJtaXNzaW9uIDIvU291cmNlX0RhdGEiCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCiMgSW1wb3J0IGluZGl2aWR1YWwgZGF0YSBmaWxlcwoKQXJwMjNfSW5oaWJpdGlvbl9EYXRhIDwtIHJlYWRfeGxzeChwYXN0ZShkYXRhX2lucHV0X3BhdGgsIGRhdGFfZmlsZSwgc2VwID0gIi8iKSwgc2hlZXQgPSAiU3VwcEZpZzVDIiwgY29sX25hbWVzID0gVFJVRSkKCkFycDIzX0luaGliaXRpb25fRGF0YSREcnVnIDwtIHJlY29kZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZywgQXJwX0luaGliX0NUUkxfNjg5ID0gIkluaGliX0NUUkxfNjg5IikKCmBgYAoKIyMgQW5hbHlzZSBBcnAyLzMgaW5oaWJpdG9yIHJlc3BvbnNlcyByZWxhdGl2ZSB0byBjb250cm9sCgojIyMgQm94cGxvdCBjaGFuZ2VzIGluIHJldGljdWxhciBhZGhlc2lvbiBiNSBpbnRlbnNpdHkyCmBgYHtyIEJveHBsb3QgY2hhbmdlcyBpbiByZXRpY3VsYXIgYWRoZXNpb24gYjUgaW50ZW5zaXR5Mn0KQXJwMjNfYjVfaW50ZW5zaXR5X2JveHBsb3RzX2ZpbGVuYW1lIDwtICJQYW5lbCBTRjVDIEFycDIzX2I1X2ludGVuc2l0eV9ib3hwbG90cyIKCmNlbGwubnVtYmVycy5BUlAyMy5zY3JlZW4gPC0gY291bnQoQXJwMjNfSW5oaWJpdGlvbl9EYXRhLCBEcnVnKQpjb3VudChBcnAyM19JbmhpYml0aW9uX0RhdGEsIERydWcpCm1lYW4uY2VsbC5udW1iZXJzLkFSUDIzLnNjcmVlbiA8LSBzdW1tYXJpc2UoY2VsbC5udW1iZXJzLkFSUDIzLnNjcmVlbiwgYXZnID0gbWVhbihuKSwgU0QgPSBzZChuKSwgc3VtKG4pKQpzdW1tYXJpc2UoY2VsbC5udW1iZXJzLkFSUDIzLnNjcmVlbiwgYXZnID0gbWVhbihuKSwgU0QgPSBzZChuKSwgc3VtKG4pKQoKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIEFycDIzX2I1X2ludGVuc2l0eV9ib3hwbG90c19maWxlbmFtZSwgIi5zdmciLCBzZXAgPSAiIiksIHdpZHRoPTcsIGhlaWdodD01KQoKcDEgPC0gZ2dwbG90KEFycDIzX0luaGliaXRpb25fRGF0YSwgYWVzKHg9RHJ1ZywgeT1NZWRpYW4uTWVhbi4uei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJJbmhpYl9DVFJMXzY4OSIsICJBcnBfSW5oaWJfNjY2IikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsKICB5bGltKC0zLCA2KSArIHlsYWIoIk1lYW4gUmV0aWN1bGFyIEFkaGVzaW9uIEludGVuc2l0eSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgojIyBwbG90IFQtQ01BQyBpbnRlbnNpdHkgWi1zY29yZSBnZ3Bsb3QyIGJveHBsb3QgLSBwZXIgRHJ1ZyAKCnAyIDwtIGdncGxvdChBcnAyM19JbmhpYml0aW9uX0RhdGEsIGFlcyh4PURydWcsIHk9TWVkaWFuLk1lYW4uX1QuQ01BQ3Muei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJJbmhpYl9DVFJMXzY4OSIsICJBcnBfSW5oaWJfNjY2IikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsKICB5bGltKC0zLCA2KSArIHlsYWIoIk1lYW4gRm9jYWwgQWRoZXNpb24gSW50ZW5zaXR5IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKIyMgcGxvdCBpbnRlbnNpdHkgcmF0aW8gWi1zY29yZSBnZ3Bsb3QyIGJveHBsb3QgLSBwZXIgRHJ1ZyAKCnAzIDwtIGdncGxvdChBcnAyM19JbmhpYml0aW9uX0RhdGEsIGFlcyh4PURydWcsIHk9UmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlLCBjb2xvciA9IGZhY3RvcihEcnVnKSkpICsgCiAgZ2VvbV9ib3hwbG90KG5vdGNoID0gVFJVRSwgb3V0bGllci5jb2xvdXIgPSAiTkEiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIkluaGliX0NUUkxfNjg5IiwgIkFycF9JbmhpYl82NjYiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3QgPSAxKSkgKwogIHlsaW0oLTMsIDYpICsgeWxhYigiUmF0aW8gUmV0aWN1bGFyOkZvY2FsIEFkaGVzaW9uIEludGVuc2l0eSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzLCBuY29sID0gMykKCmRldi5vZmYoKQoKcDEgPC0gZ2dwbG90KEFycDIzX0luaGliaXRpb25fRGF0YSwgYWVzKHg9RHJ1ZywgeT1NZWRpYW4uTWVhbi4uei5zY29yZSwgY29sb3IgPSBmYWN0b3IoRHJ1ZykpKSArIAogIGdlb21fYm94cGxvdChub3RjaCA9IFRSVUUsIG91dGxpZXIuY29sb3VyID0gIk5BIikgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJJbmhpYl9DVFJMXzY4OSIsICJBcnBfSW5oaWJfNjY2IikpICsKICB0aGVtZShheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsKICB5bGltKC0zLCA2KSArIHlsYWIoIk1lYW4gUmV0aWN1bGFyIEFkaGVzaW9uIEludGVuc2l0eSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCiMjIHBsb3QgVC1DTUFDIGludGVuc2l0eSBaLXNjb3JlIGdncGxvdDIgYm94cGxvdCAtIHBlciBEcnVnIAoKcDIgPC0gZ2dwbG90KEFycDIzX0luaGliaXRpb25fRGF0YSwgYWVzKHg9RHJ1ZywgeT1NZWRpYW4uTWVhbi5fVC5DTUFDcy56LnNjb3JlLCBjb2xvciA9IGZhY3RvcihEcnVnKSkpICsgCiAgZ2VvbV9ib3hwbG90KG5vdGNoID0gVFJVRSwgb3V0bGllci5jb2xvdXIgPSAiTkEiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIkluaGliX0NUUkxfNjg5IiwgIkFycF9JbmhpYl82NjYiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3QgPSAxKSkgKwogIHlsaW0oLTMsIDYpICsgeWxhYigiTWVhbiBGb2NhbCBBZGhlc2lvbiBJbnRlbnNpdHkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgojIyBwbG90IGludGVuc2l0eSByYXRpbyBaLXNjb3JlIGdncGxvdDIgYm94cGxvdCAtIHBlciBEcnVnIAoKcDMgPC0gZ2dwbG90KEFycDIzX0luaGliaXRpb25fRGF0YSwgYWVzKHg9RHJ1ZywgeT1SYXRpb19BLkNNQUMudG8uVC5DTUFDX21lYW5faW50ZW5zaXR5Lnouc2NvcmUsIGNvbG9yID0gZmFjdG9yKERydWcpKSkgKyAKICBnZW9tX2JveHBsb3Qobm90Y2ggPSBUUlVFLCBvdXRsaWVyLmNvbG91ciA9ICJOQSIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiSW5oaWJfQ1RSTF82ODkiLCAiQXJwX0luaGliXzY2NiIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdCA9IDEpKSArCiAgeWxpbSgtMywgNikgKyB5bGFiKCJSYXRpbyBSZXRpY3VsYXI6Rm9jYWwgQWRoZXNpb24gSW50ZW5zaXR5IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ3JpZC5hcnJhbmdlKHAxLCBwMiwgcDMsIG5jb2wgPSAzKQoKYGBgCgojIyMgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IERydWcgdHJlYXRtZW50IGVmZmVjdHMgb24gUmV0aWN1bGFyIGFkaGVzaW9uIGludGVuc2l0eTIKYGBge3IgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IERydWcgdHJlYXRtZW50IGVmZmVjdHMgb24gUmV0aWN1bGFyIGFkaGVzaW9uIGludGVuc2l0eTJ9CnBfdmFsdWVzIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkpewogIGZvciAoaiBpbiAxOmxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSl7CiAgICBEcnVnXzEgPSBzdWJzZXQoQXJwMjNfSW5oaWJpdGlvbl9EYXRhLCBBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZyA9PSB1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpW2ldKQogICAgRHJ1Z18xJERydWdfTnVtYmVyID0gYXMuZmFjdG9yKGkpCiAgICBEcnVnXzIgPSBzdWJzZXQoQXJwMjNfSW5oaWJpdGlvbl9EYXRhLCBBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZyA9PSB1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpW2pdKQogICAgRHJ1Z18yJERydWdfTnVtYmVyID0gYXMuZmFjdG9yKGorMTAwKQogICAgRHJ1Z19QYWlyID0gcmJpbmQoRHJ1Z18xLCBEcnVnXzIpCiAgICBEcnVnX1BhaXJfdHRlc3QgPSB3aWxjb3gudGVzdChNZWRpYW4uTWVhbi4uei5zY29yZSB+IERydWdfTnVtYmVyLCBkYXRhID0gRHJ1Z19QYWlyKSRwLnZhbHVlCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBEcnVnX1BhaXJfdHRlc3QpCiAgfQp9CgpwX3ZhbHVlcyA8LSBhcy52ZWN0b3IocF92YWx1ZXMpCgpwX3ZhbHVlX21hdHJpeCA8LSBtYXRyaXgocF92YWx1ZXMsbnJvdyA9IGxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSxuY29sID0gbGVuZ3RoKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKQpyb3dzIDwtIGFzLnZlY3Rvcih1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKQpwX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKHBfdmFsdWVfbWF0cml4LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhwX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKIyBwcmludChwX3ZhbHVlX2RhdGFmcmFtZSkKCiMgSW50cm9kdWNlIEhvbG0gKGFsc28gY2FsbGVkIEhvbG0tQm9uZmVycm9uaSkgcC12YWx1ZSBjb3JyZWN0aW9uICh1c2VkIGJlY2F1c2UgaXQgZ2l2ZXMgc2FtZSBzdHJpbmdlbmN5IGFnYWluc3QgZmFsc2UgcG9zaXRpdmVzICh0eXBlIDEgZXJyb3JzKSB3aXRoIGxvd2VyIHByb2JhYmlsaXR5IG9mIGZhbHNlIG5lZ2F0aXZlcyAodHlwZSAyIGVycm9ycykpKQoKY29ycmVjdGVkX3BfdmFsdWVzIDwtIHAuYWRqdXN0KHBfdmFsdWVzLCBtZXRob2QgPSAiaG9sbSIsIG4gPSBsZW5ndGgocF92YWx1ZXMpKQoKY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4NiA8LSBtYXRyaXgoY29ycmVjdGVkX3BfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUoY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4Niwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgpwcmludChjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpCmBgYAoKIyMjIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBEcnVnIHRyZWF0bWVudCBlZmZlY3RzIG9uIEZvY2FsIGFkaGVzaW9uIGludGVuc2l0eTIKYGBge3IgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IERydWcgdHJlYXRtZW50IGVmZmVjdHMgb24gRm9jYWwgYWRoZXNpb24gaW50ZW5zaXR5Mn0KcF92YWx1ZXMgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSl7CiAgZm9yIChqIGluIDE6bGVuZ3RoKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpKXsKICAgIERydWdfMSA9IHN1YnNldChBcnAyM19JbmhpYml0aW9uX0RhdGEsIEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnID09IHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZylbaV0pCiAgICBEcnVnXzEkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaSkKICAgIERydWdfMiA9IHN1YnNldChBcnAyM19JbmhpYml0aW9uX0RhdGEsIEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnID09IHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1Zylbal0pCiAgICBEcnVnXzIkRHJ1Z19OdW1iZXIgPSBhcy5mYWN0b3IoaisxMDApCiAgICBEcnVnX1BhaXIgPSByYmluZChEcnVnXzEsIERydWdfMikKICAgIERydWdfUGFpcl90dGVzdCA9IHdpbGNveC50ZXN0KE1lZGlhbi5NZWFuLl9ULkNNQUNzLnouc2NvcmUgfiBEcnVnX051bWJlciwgZGF0YSA9IERydWdfUGFpcikkcC52YWx1ZQogICAgcF92YWx1ZXMgPSByYmluZChwX3ZhbHVlcywgRHJ1Z19QYWlyX3R0ZXN0KQogIH0KfQoKcF92YWx1ZXMgPC0gYXMudmVjdG9yKHBfdmFsdWVzKQoKcF92YWx1ZV9tYXRyaXggPC0gbWF0cml4KHBfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShwX3ZhbHVlX21hdHJpeCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMocF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCiMgcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgojIEludHJvZHVjZSBIb2xtIChhbHNvIGNhbGxlZCBIb2xtLUJvbmZlcnJvbmkpIHAtdmFsdWUgY29ycmVjdGlvbiAodXNlZCBiZWNhdXNlIGl0IGdpdmVzIHNhbWUgc3RyaW5nZW5jeSBhZ2FpbnN0IGZhbHNlIHBvc2l0aXZlcyAodHlwZSAxIGVycm9ycykgd2l0aCBsb3dlciBwcm9iYWJpbGl0eSBvZiBmYWxzZSBuZWdhdGl2ZXMgKHR5cGUgMiBlcnJvcnMpKSkKCmNvcnJlY3RlZF9wX3ZhbHVlcyA8LSBwLmFkanVzdChwX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iLCBuID0gbGVuZ3RoKHBfdmFsdWVzKSkKCmNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDcgPC0gbWF0cml4KGNvcnJlY3RlZF9wX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpLG5jb2wgPSBsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkpCmNvbHVtbnMgPC0gYXMudmVjdG9yKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpCmNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDcsIHJvdy5uYW1lcyA9IHJvd3MpCm5hbWVzKGNvcnJlY3RlZF9wX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKcHJpbnQoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKQpgYGAKCiMjIyBNYW5uLVdoaXRuZXkgdGVzdCBmb3Igc2lnbmlmaWNhbnQgRHJ1ZyB0cmVhdG1lbnQgZWZmZWN0cyBvbiBpbnRlbnNpdHkgcmF0aW8gWi1zY29yZTIKYGBge3IgTWFubi1XaGl0bmV5IHRlc3QgZm9yIHNpZ25pZmljYW50IERydWcgdHJlYXRtZW50IGVmZmVjdHMgb24gaW50ZW5zaXR5IHJhdGlvIFotc2NvcmUyfQpwX3ZhbHVlcyA8LSBjKCkKZm9yIChpIGluIDE6bGVuZ3RoKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpKXsKICBmb3IgKGogaW4gMTpsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkpewogICAgRHJ1Z18xID0gc3Vic2V0KEFycDIzX0luaGliaXRpb25fRGF0YSwgQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcgPT0gdW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKVtpXSkKICAgIERydWdfMSREcnVnX051bWJlciA9IGFzLmZhY3RvcihpKQogICAgRHJ1Z18yID0gc3Vic2V0KEFycDIzX0luaGliaXRpb25fRGF0YSwgQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcgPT0gdW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKVtqXSkKICAgIERydWdfMiREcnVnX051bWJlciA9IGFzLmZhY3RvcihqKzEwMCkKICAgIERydWdfUGFpciA9IHJiaW5kKERydWdfMSwgRHJ1Z18yKQogICAgRHJ1Z19QYWlyX3R0ZXN0ID0gd2lsY294LnRlc3QoUmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlIH4gRHJ1Z19OdW1iZXIsIGRhdGEgPSBEcnVnX1BhaXIpJHAudmFsdWUgCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBEcnVnX1BhaXJfdHRlc3QpCiAgfQp9CgpwX3ZhbHVlcyA8LSBhcy52ZWN0b3IocF92YWx1ZXMpCgpwX3ZhbHVlX21hdHJpeCA8LSBtYXRyaXgocF92YWx1ZXMsbnJvdyA9IGxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSxuY29sID0gbGVuZ3RoKHVuaXF1ZShBcnAyM19JbmhpYml0aW9uX0RhdGEkRHJ1ZykpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKQpyb3dzIDwtIGFzLnZlY3Rvcih1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKQpwX3ZhbHVlX2RhdGFmcmFtZSA8LSBhcy5kYXRhLmZyYW1lKHBfdmFsdWVfbWF0cml4LCByb3cubmFtZXMgPSByb3dzKQpuYW1lcyhwX3ZhbHVlX2RhdGFmcmFtZSkgPC0gY29sdW1ucwoKIyBwcmludChwX3ZhbHVlX2RhdGFmcmFtZSkKCiMgSW50cm9kdWNlIEhvbG0gKGFsc28gY2FsbGVkIEhvbG0tQm9uZmVycm9uaSkgcC12YWx1ZSBjb3JyZWN0aW9uICh1c2VkIGJlY2F1c2UgaXQgZ2l2ZXMgc2FtZSBzdHJpbmdlbmN5IGFnYWluc3QgZmFsc2UgcG9zaXRpdmVzICh0eXBlIDEgZXJyb3JzKSB3aXRoIGxvd2VyIHByb2JhYmlsaXR5IG9mIGZhbHNlIG5lZ2F0aXZlcyAodHlwZSAyIGVycm9ycykpKQoKY29ycmVjdGVkX3BfdmFsdWVzIDwtIHAuYWRqdXN0KHBfdmFsdWVzLCBtZXRob2QgPSAiaG9sbSIsIG4gPSBsZW5ndGgocF92YWx1ZXMpKQoKY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4OCA8LSBtYXRyaXgoY29ycmVjdGVkX3BfdmFsdWVzLG5yb3cgPSBsZW5ndGgodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoQXJwMjNfSW5oaWJpdGlvbl9EYXRhJERydWcpKSkKY29sdW1ucyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKcm93cyA8LSBhcy52ZWN0b3IodW5pcXVlKEFycDIzX0luaGliaXRpb25fRGF0YSREcnVnKSkKY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUoY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4OCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgpwcmludChjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpCmBgYAoKIyBTdXBwIEZpZyA2CgojIyBJbXBvcnQgRGF0YSBTdXBwIEZpZyA2CmBgYHtyIEltcG9ydCBEYXRhIFN1cHAgRmlnIDZ9CiMgU2V0IHlvdXIgcGF0aCB0byBpbnB1dCBkYXRhCmRhdGFfaW5wdXRfcGF0aCA8LSAiL1VzZXJzL2pvaG5sb2NrL0Ryb3Bib3gvQS1DTUFDIE1hbmNoZXN0ZXIgY29sbGFib3JhdGlvbi9OQ0Igc3VibWlzc2lvbiBkb2N1bWVudHMvUmVzdWJtaXNzaW9uIDIvU291cmNlX0RhdGEiCmRhdGFfZmlsZSA8LSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxIFN0YXRpc3RpY3MgU291cmNlIERhdGEueGxzeCIKCiMgSW1wb3J0IGluZGl2aWR1YWwgZGF0YSBmaWxlcwoKU2Vjb25kYXJ5LnNpUk5BLlNjcmVlbi5EYXRhIDwtICByZWFkX3hsc3gocGFzdGUoZGF0YV9pbnB1dF9wYXRoLCBkYXRhX2ZpbGUsIHNlcCA9ICIvIiksIHNoZWV0ID0gIlN1cHBGaWc2QSIsIGNvbF9uYW1lcyA9IFRSVUUpCgpgYGAKCiMjIEFuYWx5c2UgU2Vjb25kYXJ5IHNpUk5BIFNjcmVlbiByZXNwb25zZXMKCiMjIyBCb3hwbG90IGNoYW5nZXMgaW4gcmV0aWN1bGFyIHRvIGZvY2FsIGFkaGVzaW9uIGI1IGludGVuc2l0eSByYXRpbwpgYGB7ciBCb3hwbG90IGNoYW5nZXMgaW4gcmV0aWN1bGFyIHRvIGZvY2FsIGFkaGVzaW9uIGI1IGludGVuc2l0eSByYXRpb30KU2Vjb25kYXJ5X3NpUk5BX1NjcmVlbl9ib3hwbG90c19maWxlbmFtZSA8LSAiUGFuZWwgU0Y2QSBTZWNvbmRhcnlfc2lSTkFfU2NyZWVuX2JveHBsb3Rfc3VtbWFyeSIKClNlY29uZGFyeS5zaVJOQS5TY3JlZW4uRGF0YSRzaVJOQV9UYXJnZXQgPC0gcmVjb2RlKFNlY29uZGFyeS5zaVJOQS5TY3JlZW4uRGF0YSRzaVJOQV9UYXJnZXQsIFBJSzNDMmFfMSA9ICJQSUszQzJBXzEiKQpTZWNvbmRhcnkuc2lSTkEuU2NyZWVuLkRhdGEkc2lSTkFfVGFyZ2V0IDwtIHJlY29kZShTZWNvbmRhcnkuc2lSTkEuU2NyZWVuLkRhdGEkc2lSTkFfVGFyZ2V0LCBQSUszQzJhXzIgPSAiUElLM0MyQV8yIikKU2Vjb25kYXJ5LnNpUk5BLlNjcmVlbi5EYXRhJHNpUk5BX1RhcmdldCA8LSByZWNvZGUoU2Vjb25kYXJ5LnNpUk5BLlNjcmVlbi5EYXRhJHNpUk5BX1RhcmdldCwgUElLM0MyYV8zID0gIlBJSzNDMkFfMyIpClNlY29uZGFyeS5zaVJOQS5TY3JlZW4uRGF0YSRzaVJOQV9UYXJnZXQgPC0gcmVjb2RlKFNlY29uZGFyeS5zaVJOQS5TY3JlZW4uRGF0YSRzaVJOQV9UYXJnZXQsIFBJSzNDMmFfNCA9ICJQSUszQzJBXzQiKQoKY2VsbC5udW1iZXJzLnNlY29uZGFyeS5zY3JlZW4gPC0gY291bnQoU2Vjb25kYXJ5LnNpUk5BLlNjcmVlbi5EYXRhLCBzaVJOQV9UYXJnZXQpCmNvdW50KFNlY29uZGFyeS5zaVJOQS5TY3JlZW4uRGF0YSwgc2lSTkFfVGFyZ2V0KQptZWFuLmNlbGwubnVtYmVycy5zZWNvbmRhcnkuc2NyZWVuIDwtIHN1bW1hcmlzZShjZWxsLm51bWJlcnMuc2Vjb25kYXJ5LnNjcmVlbiwgYXZnID0gbWVhbihuKSwgU0QgPSBzZChuKSwgc3VtKG4pKQpzdW1tYXJpc2UoY2VsbC5udW1iZXJzLnNlY29uZGFyeS5zY3JlZW4sIGF2ZyA9IG1lYW4obiksIFNEID0gc2QobiksIHN1bShuKSkKCnN2Z2xpdGUocGFzdGUocGFuZWxfb3V0cHV0X3BhdGgsIFNlY29uZGFyeV9zaVJOQV9TY3JlZW5fYm94cGxvdHNfZmlsZW5hbWUsICIuc3ZnIiwgc2VwID0gIiIpLCB3aWR0aD03LCBoZWlnaHQ9NSkKCmdncGxvdChTZWNvbmRhcnkuc2lSTkEuU2NyZWVuLkRhdGEsIGFlcyh4PXNpUk5BX1RhcmdldCwgeT1SYXRpb19BLkNNQUMudG8uVC5DTUFDX21lYW5faW50ZW5zaXR5Lnouc2NvcmUsIGNvbG9yID0gZmFjdG9yKHNpUk5BX1RyZWF0bWVudF9UeXBlKSkpICsKICBnZW9tX2JveHBsb3Qobm90Y2ggPSBUUlVFLCBvdXRsaWVyLmNvbG91ciA9ICJOQSIpICArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTkwKSkgKwogIHlsaW0oLTMsIDYpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiVW50cmVhdGVkIiwiTU9DSyIsIlNTVF8zQ3RybF9Qb29sIiwgIk9OLVRBUkdFVHBsdXMgTm9uLXRhcmdldGluZyBDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2lHRU5PTUUgTm9uLXRhcmdldGluZyBDb250cm9sIiwgIkVHRlAiLCAiSVRHQVYiLCAiSVRHQjUiLCAiT0NSTF8xIiwgIk9DUkxfMiIsICJPQ1JMXzMiLCAiT0NSTF80IiwgIlBJNEsyQV8xIiwgIlBJNEsyQV8yIiwgIlBJNEsyQV8zIiwgIlBJNEsyQV80IiwgIlBJNEtBXzEiLCAiUEk0S0FfMiIsICJQSTRLQV8zIiwgIlBJNEtBXzQiLCAiUElQNUsxQl8xIiwgIlBJUDVLMUJfMiIsICJQSVA1SzFCXzMiLCAiUElQNUsxQl80IiwgIlBJUDVLMUNfMSIsICJQSVA1SzFDXzIiLCAiUElQNUsxQ18zIiwgIlBJUDVLMUNfNCIsICJQVEVOXzEiLCAiUFRFTl8yIiwgIlBURU5fMyIsICJQVEVOXzQiLCAiUElLM0MyQV8xIiwgIlBJSzNDMkFfMiIsICJQSUszQzJBXzMiLCAiUElLM0MyQV80IikpCgpkZXYub2ZmKCkKCmdncGxvdChTZWNvbmRhcnkuc2lSTkEuU2NyZWVuLkRhdGEsIGFlcyh4PXNpUk5BX1RhcmdldCwgeT1SYXRpb19BLkNNQUMudG8uVC5DTUFDX21lYW5faW50ZW5zaXR5Lnouc2NvcmUsIGNvbG9yID0gZmFjdG9yKHNpUk5BX1RyZWF0bWVudF9UeXBlKSkpICsKICBnZW9tX2JveHBsb3Qobm90Y2ggPSBUUlVFLCBvdXRsaWVyLmNvbG91ciA9ICJOQSIpICArCiAgdGhlbWUoYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KGFuZ2xlPTkwKSkgKwogIHlsaW0oLTMsIDYpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiVW50cmVhdGVkIiwiTU9DSyIsIlNTVF8zQ3RybF9Qb29sIiwgIk9OLVRBUkdFVHBsdXMgTm9uLXRhcmdldGluZyBDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2lHRU5PTUUgTm9uLXRhcmdldGluZyBDb250cm9sIiwgIkVHRlAiLCAiSVRHQVYiLCAiSVRHQjUiLCAiT0NSTF8xIiwgIk9DUkxfMiIsICJPQ1JMXzMiLCAiT0NSTF80IiwgIlBJNEsyQV8xIiwgIlBJNEsyQV8yIiwgIlBJNEsyQV8zIiwgIlBJNEsyQV80IiwgIlBJNEtBXzEiLCAiUEk0S0FfMiIsICJQSTRLQV8zIiwgIlBJNEtBXzQiLCAiUElQNUsxQl8xIiwgIlBJUDVLMUJfMiIsICJQSVA1SzFCXzMiLCAiUElQNUsxQl80IiwgIlBJUDVLMUNfMSIsICJQSVA1SzFDXzIiLCAiUElQNUsxQ18zIiwgIlBJUDVLMUNfNCIsICJQVEVOXzEiLCAiUFRFTl8yIiwgIlBURU5fMyIsICJQVEVOXzQiLCAiUElLM0MyQV8xIiwgIlBJSzNDMkFfMiIsICJQSUszQzJBXzMiLCAiUElLM0MyQV80IikpCgpgYGAKCiMjIyBNYW5uLVdoaXRuZXkgdGVzdCBmb3Igc2lnbmlmaWNhbnQgc2lSTkEgdHJlYXRtZW50IGVmZmVjdHMyCmBgYHtyIE1hbm4tV2hpdG5leSB0ZXN0IGZvciBzaWduaWZpY2FudCBzaVJOQSB0cmVhdG1lbnQgZWZmZWN0czJ9CnNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCA8LSBzdWJzZXQoU2Vjb25kYXJ5LnNpUk5BLlNjcmVlbi5EYXRhLCBzaVJOQV9UYXJnZXQgIT0gIlVudHJlYXRlZCIgJiBzaVJOQV9UYXJnZXQgIT0gIk1PQ0siICYgc2lSTkFfVGFyZ2V0ICE9ICJTU1RfM0N0cmxfUG9vbCIgJiBzaVJOQV9UYXJnZXQgIT0gInNpR0VOT01FIE5vbi10YXJnZXRpbmcgQ29udHJvbCIpIAoKcF92YWx1ZXMgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKXsKICBmb3IgKGogaW4gMTpsZW5ndGgodW5pcXVlKHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQpKSl7CiAgICBzaVJOQV9UYXJnZXRfMSA9IHN1YnNldChzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3QsIHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQgPT0gdW5pcXVlKHNpUk5BLmNvbmRpdGlvbnMuZm9yLlUudGVzdCRzaVJOQV9UYXJnZXQpW2ldKQogICAgc2lSTkFfVGFyZ2V0XzEkc2lSTkFfVGFyZ2V0X051bWJlciA9IGFzLmZhY3RvcihpKQogICAgc2lSTkFfVGFyZ2V0XzIgPSBzdWJzZXQoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0LCBzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0ID09IHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KVtqXSkKICAgIHNpUk5BX1RhcmdldF8yJHNpUk5BX1RhcmdldF9OdW1iZXIgPSBhcy5mYWN0b3IoaisxMDApCiAgICBzaVJOQV9UYXJnZXRfUGFpciA9IHJiaW5kKHNpUk5BX1RhcmdldF8xLCBzaVJOQV9UYXJnZXRfMikKICAgIHNpUk5BX1RhcmdldF9QYWlyX3R0ZXN0ID0gd2lsY294LnRlc3QoUmF0aW9fQS5DTUFDLnRvLlQuQ01BQ19tZWFuX2ludGVuc2l0eS56LnNjb3JlIH4gc2lSTkFfVGFyZ2V0X051bWJlciwgZGF0YSA9IHNpUk5BX1RhcmdldF9QYWlyKSRwLnZhbHVlCiAgICBwX3ZhbHVlcyA9IHJiaW5kKHBfdmFsdWVzLCBzaVJOQV9UYXJnZXRfUGFpcl90dGVzdCkKICB9Cn0KCnBfdmFsdWVzIDwtIGFzLnZlY3RvcihwX3ZhbHVlcykKCnBfdmFsdWVfbWF0cml4IDwtIG1hdHJpeChwX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSkKcF92YWx1ZV9kYXRhZnJhbWUgPC0gYXMuZGF0YS5mcmFtZShwX3ZhbHVlX21hdHJpeCwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMocF92YWx1ZV9kYXRhZnJhbWUpIDwtIGNvbHVtbnMKCiMgcHJpbnQocF92YWx1ZV9kYXRhZnJhbWUpCgojIEludHJvZHVjZSBIb2xtIChhbHNvIGNhbGxlZCBIb2xtLUJvbmZlcnJvbmkpIHAtdmFsdWUgY29ycmVjdGlvbiAodXNlZCBiZWNhdXNlIGl0IGdpdmVzIHNhbWUgc3RyaW5nZW5jeSBhZ2FpbnN0IGZhbHNlIHBvc2l0aXZlcyAodHlwZSAxIGVycm9ycykgd2l0aCBsb3dlciBwcm9iYWJpbGl0eSBvZiBmYWxzZSBuZWdhdGl2ZXMgKHR5cGUgMiBlcnJvcnMpKSkKCmNvcnJlY3RlZF9wX3ZhbHVlcyA8LSBwLmFkanVzdChwX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iLCBuID0gbGVuZ3RoKHBfdmFsdWVzKSkKCmNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDkgPC0gbWF0cml4KGNvcnJlY3RlZF9wX3ZhbHVlcyxucm93ID0gbGVuZ3RoKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSksbmNvbCA9IGxlbmd0aCh1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpKQpjb2x1bW5zIDwtIGFzLnZlY3Rvcih1bmlxdWUoc2lSTkEuY29uZGl0aW9ucy5mb3IuVS50ZXN0JHNpUk5BX1RhcmdldCkpCnJvd3MgPC0gYXMudmVjdG9yKHVuaXF1ZShzaVJOQS5jb25kaXRpb25zLmZvci5VLnRlc3Qkc2lSTkFfVGFyZ2V0KSkKY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lIDwtIGFzLmRhdGEuZnJhbWUoY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4OSwgcm93Lm5hbWVzID0gcm93cykKbmFtZXMoY29ycmVjdGVkX3BfdmFsdWVfZGF0YWZyYW1lKSA8LSBjb2x1bW5zCgpwcmludChjb3JyZWN0ZWRfcF92YWx1ZV9kYXRhZnJhbWUpCgpgYGAKCiMjIyBQbG90IGhlYXRtYXAgb2YgY29ycmVjdGVkIHBfdmFsdWVzMgpgYGB7ciBQbG90IGhlYXRtYXAgb2YgY29ycmVjdGVkIHBfdmFsdWVzMiwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OH0KaGVhdG1hcC4yKGxvZyhjb3JyZWN0ZWRfcF92YWx1ZV9tYXRyaXg5KSwgZGVuZHJvZ3JhbSA9ICdub25lJywgUm93diA9IEZBTFNFLCBDb2x2ID0gRkFMU0UsIGxhYlJvdyA9IHJvd3MsIGxhYkNvbCA9IGNvbHVtbnMsIHNydENvbCA9IDQ1LCBjZXhSb3cgPSAxLCBjZXhDb2wgPSAxLCBtYXJnaW5zID0gYyg3LCA5KSwgc3ltbSA9IFRSVUUsIHJldkMgPSBGQUxTRSwgYnJlYWtzID0gYyhsb2coMWUtMzAwKSwgbG9nKDFlLTUwKSwgbG9nKDFlLTEwKSwgbG9nKDFlLTYpLCBsb2coMC4wMDEpLCBsb2coMC4wMSksIGxvZygwLjA1KSwgbG9nKDEpKSwgcm93c2VwID0gMTpucm93KGNvcnJlY3RlZF9wX3ZhbHVlX21hdHJpeDkpLCBjb2xzZXAgPSAxOm5jb2woY29ycmVjdGVkX3BfdmFsdWVfbWF0cml4OSksIHNlcGNvbG9yID0gJ2RhcmtncmV5Jywgc2Vwd2lkdGggPSBjKDAuMDIsMC4wMiksIHRyYWNlID0gJ25vbmUnLCBjb2wgPSBjKCJkYXJrcmVkIiwgInJlZCIsICJvcmFuZ2UiLCAiZ3JlZW4iLCAiYmx1ZSIsICJwdXJwbGUiLCAibGlnaHRncmV5IiksIGRlbnNjb2wgPSBOVUxMLCBrZXlzaXplID0gMS41LCBrZXkudGl0bGUgPSBOQSkKYGBg